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.nio.ByteBuffer;
022import java.util.List;
023import java.util.Map;
024import java.util.NavigableMap;
025import java.util.UUID;
026import org.apache.hadoop.hbase.Cell;
027import org.apache.hadoop.hbase.CellBuilder;
028import org.apache.hadoop.hbase.CellBuilderType;
029import org.apache.hadoop.hbase.ExtendedCell;
030import org.apache.hadoop.hbase.HConstants;
031import org.apache.hadoop.hbase.KeyValue;
032import org.apache.hadoop.hbase.io.HeapSize;
033import org.apache.hadoop.hbase.security.access.Permission;
034import org.apache.hadoop.hbase.security.visibility.CellVisibility;
035import org.apache.hadoop.hbase.util.Bytes;
036import org.apache.yetus.audience.InterfaceAudience;
037
038/**
039 * Used to perform Put operations for a single row.
040 * <p>
041 * To perform a Put, instantiate a Put object with the row to insert to, and for each column to be
042 * inserted, execute {@link #addColumn(byte[], byte[], byte[]) add} or
043 * {@link #addColumn(byte[], byte[], long, byte[]) add} if setting the timestamp.
044 */
045@InterfaceAudience.Public
046public class Put extends Mutation implements HeapSize {
047  /**
048   * Create a Put operation for the specified row.
049   * @param row row key
050   */
051  public Put(byte[] row) {
052    this(row, HConstants.LATEST_TIMESTAMP);
053  }
054
055  /**
056   * Create a Put operation for the specified row, using a given timestamp.
057   * @param row row key; we make a copy of what we are passed to keep local.
058   * @param ts  timestamp
059   */
060  public Put(byte[] row, long ts) {
061    this(row, 0, row.length, ts);
062  }
063
064  /**
065   * We make a copy of the passed in row key to keep local.
066   */
067  public Put(byte[] rowArray, int rowOffset, int rowLength) {
068    this(rowArray, rowOffset, rowLength, HConstants.LATEST_TIMESTAMP);
069  }
070
071  /**
072   * @param row row key; we make a copy of what we are passed to keep local.
073   * @param ts  timestamp
074   */
075  public Put(ByteBuffer row, long ts) {
076    if (ts < 0) {
077      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts);
078    }
079    checkRow(row);
080    this.row = new byte[row.remaining()];
081    row.get(this.row);
082    this.ts = ts;
083  }
084
085  /**
086   * @param row row key; we make a copy of what we are passed to keep local.
087   */
088  public Put(ByteBuffer row) {
089    this(row, HConstants.LATEST_TIMESTAMP);
090  }
091
092  /**
093   * We make a copy of the passed in row key to keep local.
094   */
095  public Put(byte[] rowArray, int rowOffset, int rowLength, long ts) {
096    checkRow(rowArray, rowOffset, rowLength);
097    checkTimestamp(ts);
098    this.row = Bytes.copy(rowArray, rowOffset, rowLength);
099    this.ts = ts;
100  }
101
102  /**
103   * Create a Put operation for an immutable row key.
104   * @param row            row key
105   * @param rowIsImmutable whether the input row is immutable. Set to true if the caller can
106   *                       guarantee that the row will not be changed for the Put duration.
107   */
108  public Put(byte[] row, boolean rowIsImmutable) {
109    this(row, HConstants.LATEST_TIMESTAMP, rowIsImmutable);
110  }
111
112  /**
113   * Create a Put operation for an immutable row key, using a given timestamp.
114   * @param row            row key
115   * @param ts             timestamp
116   * @param rowIsImmutable whether the input row is immutable. Set to true if the caller can
117   *                       guarantee that the row will not be changed for the Put duration.
118   */
119  public Put(byte[] row, long ts, boolean rowIsImmutable) {
120    // Check and set timestamp
121    checkTimestamp(ts);
122    this.ts = ts;
123
124    // Deal with row according to rowIsImmutable
125    checkRow(row);
126    if (rowIsImmutable) { // Row is immutable
127      this.row = row; // Do not make a local copy, but point to the provided byte array directly
128    } else { // Row is not immutable
129      this.row = Bytes.copy(row, 0, row.length); // Make a local copy
130    }
131  }
132
133  /**
134   * Copy constructor. Creates a Put operation cloned from the specified Put.
135   * @param putToCopy put to copy
136   */
137  public Put(Put putToCopy) {
138    super(putToCopy);
139  }
140
141  /**
142   * Construct the Put with user defined data. NOTED: 1) all cells in the familyMap must have the
143   * Type.Put 2) the row of each cell must be same with passed row.
144   * @param row       row. CAN'T be null
145   * @param ts        timestamp
146   * @param familyMap the map to collect all cells internally. CAN'T be null
147   */
148  public Put(byte[] row, long ts, NavigableMap<byte[], List<Cell>> familyMap) {
149    super(row, ts, familyMap);
150  }
151
152  /**
153   * Add the specified column and value to this Put operation.
154   * @param family    family name
155   * @param qualifier column qualifier
156   * @param value     column value
157   */
158  public Put addColumn(byte[] family, byte[] qualifier, byte[] value) {
159    return addColumn(family, qualifier, this.ts, value);
160  }
161
162  /**
163   * Add the specified column and value, with the specified timestamp as its version to this Put
164   * operation.
165   * @param family    family name
166   * @param qualifier column qualifier
167   * @param ts        version timestamp
168   * @param value     column value
169   */
170  public Put addColumn(byte[] family, byte[] qualifier, long ts, byte[] value) {
171    checkTimestamp(ts);
172    List<ExtendedCell> list = getCellList(family);
173    KeyValue kv = createPutKeyValue(family, qualifier, ts, value);
174    list.add(kv);
175    return this;
176  }
177
178  /**
179   * Add the specified column and value, with the specified timestamp as its version to this Put
180   * operation.
181   * @param family    family name
182   * @param qualifier column qualifier
183   * @param ts        version timestamp
184   * @param value     column value
185   */
186  public Put addColumn(byte[] family, ByteBuffer qualifier, long ts, ByteBuffer value) {
187    checkTimestamp(ts);
188    List<ExtendedCell> list = getCellList(family);
189    KeyValue kv = createPutKeyValue(family, qualifier, ts, value, null);
190    list.add(kv);
191    return this;
192  }
193
194  /**
195   * Add the specified KeyValue to this Put operation. Operation assumes that the passed KeyValue is
196   * immutable and its backing array will not be modified for the duration of this Put.
197   * @param cell individual cell
198   * @throws java.io.IOException e
199   */
200  @Override
201  public Put add(Cell cell) throws IOException {
202    super.add(cell);
203    return this;
204  }
205
206  @Override
207  public Put setTimestamp(long timestamp) {
208    super.setTimestamp(timestamp);
209    return this;
210  }
211
212  @Override
213  public Put setAttribute(String name, byte[] value) {
214    return (Put) super.setAttribute(name, value);
215  }
216
217  @Override
218  public Put setId(String id) {
219    return (Put) super.setId(id);
220  }
221
222  @Override
223  public Put setDurability(Durability d) {
224    return (Put) super.setDurability(d);
225  }
226
227  @Override
228  public Put setClusterIds(List<UUID> clusterIds) {
229    return (Put) super.setClusterIds(clusterIds);
230  }
231
232  @Override
233  public Put setCellVisibility(CellVisibility expression) {
234    return (Put) super.setCellVisibility(expression);
235  }
236
237  @Override
238  public Put setACL(String user, Permission perms) {
239    return (Put) super.setACL(user, perms);
240  }
241
242  @Override
243  public Put setACL(Map<String, Permission> perms) {
244    return (Put) super.setACL(perms);
245  }
246
247  @Override
248  public Put setTTL(long ttl) {
249    return (Put) super.setTTL(ttl);
250  }
251
252  @Override
253  public Put setPriority(int priority) {
254    return (Put) super.setPriority(priority);
255  }
256
257  @Override
258  public CellBuilder getCellBuilder(CellBuilderType type) {
259    return getCellBuilder(type, Cell.Type.Put);
260  }
261
262}