001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import java.io.IOException; 021import java.util.List; 022import java.util.Map; 023import java.util.NavigableMap; 024import java.util.UUID; 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.CellBuilder; 027import org.apache.hadoop.hbase.CellBuilderType; 028import org.apache.hadoop.hbase.KeyValue; 029import org.apache.hadoop.hbase.io.TimeRange; 030import org.apache.hadoop.hbase.security.access.Permission; 031import org.apache.hadoop.hbase.security.visibility.CellVisibility; 032import org.apache.hadoop.hbase.util.Bytes; 033import org.apache.hadoop.hbase.util.ClassSize; 034import org.apache.yetus.audience.InterfaceAudience; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038/** 039 * Performs Append operations on a single row. 040 * <p> 041 * This operation ensures atomicty to readers. Appends are done 042 * under a single row lock, so write operations to a row are synchronized, and 043 * readers are guaranteed to see this operation fully completed. 044 * <p> 045 * To append to a set of columns of a row, instantiate an Append object with the 046 * row to append to. At least one column to append must be specified using the 047 * {@link #addColumn(byte[], byte[], byte[])} method. 048 */ 049@InterfaceAudience.Public 050public class Append extends Mutation { 051 private static final Logger LOG = LoggerFactory.getLogger(Append.class); 052 private static final long HEAP_OVERHEAD = ClassSize.REFERENCE + ClassSize.TIMERANGE; 053 private TimeRange tr = TimeRange.allTime(); 054 055 /** 056 * Sets the TimeRange to be used on the Get for this append. 057 * <p> 058 * This is useful for when you have counters that only last for specific 059 * periods of time (ie. counters that are partitioned by time). By setting 060 * the range of valid times for this append, you can potentially gain 061 * some performance with a more optimal Get operation. 062 * Be careful adding the time range to this class as you will update the old cell if the 063 * time range doesn't include the latest cells. 064 * <p> 065 * This range is used as [minStamp, maxStamp). 066 * @param minStamp minimum timestamp value, inclusive 067 * @param maxStamp maximum timestamp value, exclusive 068 * @return this 069 */ 070 public Append setTimeRange(long minStamp, long maxStamp) { 071 tr = TimeRange.between(minStamp, maxStamp); 072 return this; 073 } 074 075 /** 076 * Gets the TimeRange used for this append. 077 * @return TimeRange 078 */ 079 public TimeRange getTimeRange() { 080 return this.tr; 081 } 082 083 @Override 084 protected long extraHeapSize(){ 085 return HEAP_OVERHEAD; 086 } 087 088 /** 089 * @param returnResults 090 * True (default) if the append operation should return the results. 091 * A client that is not interested in the result can save network 092 * bandwidth setting this to false. 093 */ 094 @Override 095 public Append setReturnResults(boolean returnResults) { 096 super.setReturnResults(returnResults); 097 return this; 098 } 099 100 /** 101 * @return current setting for returnResults 102 */ 103 // This method makes public the superclasses's protected method. 104 @Override 105 public boolean isReturnResults() { 106 return super.isReturnResults(); 107 } 108 109 /** 110 * Create a Append operation for the specified row. 111 * <p> 112 * At least one column must be appended to. 113 * @param row row key; makes a local copy of passed in array. 114 */ 115 public Append(byte[] row) { 116 this(row, 0, row.length); 117 } 118 /** 119 * Copy constructor 120 * @param appendToCopy append to copy 121 */ 122 public Append(Append appendToCopy) { 123 super(appendToCopy); 124 this.tr = appendToCopy.getTimeRange(); 125 } 126 127 /** Create a Append operation for the specified row. 128 * <p> 129 * At least one column must be appended to. 130 * @param rowArray Makes a copy out of this buffer. 131 * @param rowOffset 132 * @param rowLength 133 */ 134 public Append(final byte [] rowArray, final int rowOffset, final int rowLength) { 135 checkRow(rowArray, rowOffset, rowLength); 136 this.row = Bytes.copy(rowArray, rowOffset, rowLength); 137 } 138 139 /** 140 * Construct the Append with user defined data. NOTED: 141 * 1) all cells in the familyMap must have the Type.Put 142 * 2) the row of each cell must be same with passed row. 143 * @param row row. CAN'T be null 144 * @param ts timestamp 145 * @param familyMap the map to collect all cells internally. CAN'T be null 146 */ 147 public Append(byte[] row, long ts, NavigableMap<byte [], List<Cell>> familyMap) { 148 super(row, ts, familyMap); 149 } 150 151 /** 152 * Add the specified column and value to this Append operation. 153 * @param family family name 154 * @param qualifier column qualifier 155 * @param value value to append to specified column 156 * @return this 157 */ 158 public Append addColumn(byte[] family, byte[] qualifier, byte[] value) { 159 KeyValue kv = new KeyValue(this.row, family, qualifier, this.ts, KeyValue.Type.Put, value); 160 return add(kv); 161 } 162 163 /** 164 * Add column and value to this Append operation. 165 * @return This instance 166 */ 167 @Override 168 public Append add(final Cell cell) { 169 try { 170 super.add(cell); 171 } catch (IOException e) { 172 // we eat the exception of wrong row for BC.. 173 LOG.error(e.toString(), e); 174 } 175 return this; 176 } 177 178 @Override 179 public Append setTimestamp(long timestamp) { 180 super.setTimestamp(timestamp); 181 return this; 182 } 183 184 @Override 185 public Append setAttribute(String name, byte[] value) { 186 return (Append) super.setAttribute(name, value); 187 } 188 189 @Override 190 public Append setId(String id) { 191 return (Append) super.setId(id); 192 } 193 194 @Override 195 public Append setDurability(Durability d) { 196 return (Append) super.setDurability(d); 197 } 198 199 @Override 200 public Append setClusterIds(List<UUID> clusterIds) { 201 return (Append) super.setClusterIds(clusterIds); 202 } 203 204 @Override 205 public Append setCellVisibility(CellVisibility expression) { 206 return (Append) super.setCellVisibility(expression); 207 } 208 209 @Override 210 public Append setACL(String user, Permission perms) { 211 return (Append) super.setACL(user, perms); 212 } 213 214 @Override 215 public Append setACL(Map<String, Permission> perms) { 216 return (Append) super.setACL(perms); 217 } 218 219 @Override 220 public Append setPriority(int priority) { 221 return (Append) super.setPriority(priority); 222 } 223 224 @Override 225 public Append setTTL(long ttl) { 226 return (Append) super.setTTL(ttl); 227 } 228 229 @Override 230 public CellBuilder getCellBuilder(CellBuilderType type) { 231 return getCellBuilder(type, Cell.Type.Put); 232 } 233}