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