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