1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 package org.apache.hadoop.hbase.client; 19 20 import java.util.ArrayList; 21 import java.util.List; 22 23 import org.apache.hadoop.classification.InterfaceAudience; 24 import org.apache.hadoop.classification.InterfaceStability; 25 import org.apache.hadoop.hbase.Cell; 26 import org.apache.hadoop.hbase.KeyValue; 27 import org.apache.hadoop.hbase.KeyValueUtil; 28 import org.apache.hadoop.hbase.util.Bytes; 29 30 /** 31 * Performs Append operations on a single row. 32 * <p> 33 * Note that this operation does not appear atomic to readers. Appends are done 34 * under a single row lock, so write operations to a row are synchronized, but 35 * readers do not take row locks so get and scan operations can see this 36 * operation partially completed. 37 * <p> 38 * To append to a set of columns of a row, instantiate an Append object with the 39 * row to append to. At least one column to append must be specified using the 40 * {@link #add(byte[], byte[], byte[])} method. 41 */ 42 @InterfaceAudience.Public 43 @InterfaceStability.Stable 44 public class Append extends Mutation { 45 private static final String RETURN_RESULTS = "_rr_"; 46 /** 47 * @param returnResults 48 * True (default) if the append operation should return the results. 49 * A client that is not interested in the result can save network 50 * bandwidth setting this to false. 51 */ 52 public void setReturnResults(boolean returnResults) { 53 setAttribute(RETURN_RESULTS, Bytes.toBytes(returnResults)); 54 } 55 56 /** 57 * @return current setting for returnResults 58 */ 59 public boolean isReturnResults() { 60 byte[] v = getAttribute(RETURN_RESULTS); 61 return v == null ? true : Bytes.toBoolean(v); 62 } 63 64 /** 65 * Create a Append operation for the specified row. 66 * <p> 67 * At least one column must be appended to. 68 * @param row row key; makes a local copy of passed in array. 69 */ 70 public Append(byte[] row) { 71 this(row, 0, row.length); 72 } 73 74 /** Create a Append operation for the specified row. 75 * <p> 76 * At least one column must be appended to. 77 * @param rowArray Makes a copy out of this buffer. 78 * @param rowOffset 79 * @param rowLength 80 */ 81 public Append(final byte [] rowArray, final int rowOffset, final int rowLength) { 82 checkRow(rowArray, rowOffset, rowLength); 83 this.row = Bytes.copy(rowArray, rowOffset, rowLength); 84 } 85 86 /** 87 * Add the specified column and value to this Append operation. 88 * @param family family name 89 * @param qualifier column qualifier 90 * @param value value to append to specified column 91 * @return this 92 */ 93 public Append add(byte [] family, byte [] qualifier, byte [] value) { 94 KeyValue kv = new KeyValue(this.row, family, qualifier, this.ts, KeyValue.Type.Put, value); 95 return add(kv); 96 } 97 98 /** 99 * Add column and value to this Append operation. 100 * @param cell 101 * @return This instance 102 */ 103 @SuppressWarnings("unchecked") 104 public Append add(final Cell cell) { 105 // Presume it is KeyValue for now. 106 KeyValue kv = KeyValueUtil.ensureKeyValue(cell); 107 byte [] family = kv.getFamily(); 108 List<? extends Cell> list = this.familyMap.get(family); 109 if (list == null) { 110 list = new ArrayList<Cell>(); 111 } 112 // Cast so explicit list type rather than ? extends Cell. Help the compiler out. See 113 // http://stackoverflow.com/questions/6474784/java-using-generics-with-lists-and-interfaces 114 ((List<KeyValue>)list).add(kv); 115 this.familyMap.put(family, list); 116 return this; 117 } 118 }