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 import java.util.Map; 23 24 import org.apache.hadoop.hbase.classification.InterfaceAudience; 25 import org.apache.hadoop.hbase.classification.InterfaceStability; 26 import org.apache.hadoop.hbase.Cell; 27 import org.apache.hadoop.hbase.KeyValue; 28 import org.apache.hadoop.hbase.KeyValueUtil; 29 import org.apache.hadoop.hbase.util.Bytes; 30 31 /** 32 * Performs Append operations on a single row. 33 * <p> 34 * Note that this operation does not appear atomic to readers. Appends are done 35 * under a single row lock, so write operations to a row are synchronized, but 36 * readers do not take row locks so get and scan operations can see this 37 * operation partially completed. 38 * <p> 39 * To append to a set of columns of a row, instantiate an Append object with the 40 * row to append to. At least one column to append must be specified using the 41 * {@link #add(byte[], byte[], byte[])} method. 42 */ 43 @InterfaceAudience.Public 44 @InterfaceStability.Stable 45 public class Append extends Mutation { 46 private static final String RETURN_RESULTS = "_rr_"; 47 /** 48 * @param returnResults 49 * True (default) if the append operation should return the results. 50 * A client that is not interested in the result can save network 51 * bandwidth setting this to false. 52 */ 53 public void setReturnResults(boolean returnResults) { 54 setAttribute(RETURN_RESULTS, Bytes.toBytes(returnResults)); 55 } 56 57 /** 58 * @return current setting for returnResults 59 */ 60 public boolean isReturnResults() { 61 byte[] v = getAttribute(RETURN_RESULTS); 62 return v == null ? true : Bytes.toBoolean(v); 63 } 64 65 /** 66 * Create a Append operation for the specified row. 67 * <p> 68 * At least one column must be appended to. 69 * @param row row key; makes a local copy of passed in array. 70 */ 71 public Append(byte[] row) { 72 this(row, 0, row.length); 73 } 74 /** 75 * Copy constructor 76 * @param a 77 */ 78 public Append(Append a) { 79 this.row = a.getRow(); 80 this.ts = a.getTimeStamp(); 81 this.familyMap.putAll(a.getFamilyCellMap()); 82 for (Map.Entry<String, byte[]> entry : a.getAttributesMap().entrySet()) { 83 this.setAttribute(entry.getKey(), entry.getValue()); 84 } 85 } 86 87 /** Create a Append operation for the specified row. 88 * <p> 89 * At least one column must be appended to. 90 * @param rowArray Makes a copy out of this buffer. 91 * @param rowOffset 92 * @param rowLength 93 */ 94 public Append(final byte [] rowArray, final int rowOffset, final int rowLength) { 95 checkRow(rowArray, rowOffset, rowLength); 96 this.row = Bytes.copy(rowArray, rowOffset, rowLength); 97 } 98 99 /** 100 * Add the specified column and value to this Append operation. 101 * @param family family name 102 * @param qualifier column qualifier 103 * @param value value to append to specified column 104 * @return this 105 */ 106 public Append add(byte [] family, byte [] qualifier, byte [] value) { 107 KeyValue kv = new KeyValue(this.row, family, qualifier, this.ts, KeyValue.Type.Put, value); 108 return add(kv); 109 } 110 111 /** 112 * Add column and value to this Append operation. 113 * @param cell 114 * @return This instance 115 */ 116 @SuppressWarnings("unchecked") 117 public Append add(final Cell cell) { 118 // Presume it is KeyValue for now. 119 KeyValue kv = KeyValueUtil.ensureKeyValue(cell); 120 byte [] family = kv.getFamily(); 121 List<Cell> list = this.familyMap.get(family); 122 if (list == null) { 123 list = new ArrayList<Cell>(); 124 } 125 // find where the new entry should be placed in the List 126 list.add(kv); 127 this.familyMap.put(family, list); 128 return this; 129 } 130 }