001/*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.client;
021
022import java.io.IOException;
023import java.nio.ByteBuffer;
024import java.util.List;
025import java.util.Map;
026import java.util.NavigableMap;
027import java.util.UUID;
028import org.apache.hadoop.hbase.Cell;
029import org.apache.hadoop.hbase.CellBuilder;
030import org.apache.hadoop.hbase.CellBuilderType;
031import org.apache.hadoop.hbase.HConstants;
032import org.apache.hadoop.hbase.KeyValue;
033import org.apache.hadoop.hbase.io.HeapSize;
034import org.apache.hadoop.hbase.security.access.Permission;
035import org.apache.hadoop.hbase.security.visibility.CellVisibility;
036import org.apache.hadoop.hbase.util.Bytes;
037import org.apache.yetus.audience.InterfaceAudience;
038
039/**
040 * Used to perform Put operations for a single row.
041 * <p>
042 * To perform a Put, instantiate a Put object with the row to insert to, and
043 * for each column to be inserted, execute {@link #addColumn(byte[], byte[],
044 * byte[]) add} or {@link #addColumn(byte[], byte[], long, byte[]) add} if
045 * setting the timestamp.
046 */
047@InterfaceAudience.Public
048public class Put extends Mutation implements HeapSize {
049  /**
050   * Create a Put operation for the specified row.
051   * @param row row key
052   */
053  public Put(byte [] row) {
054    this(row, HConstants.LATEST_TIMESTAMP);
055  }
056
057  /**
058   * Create a Put operation for the specified row, using a given timestamp.
059   *
060   * @param row row key; we make a copy of what we are passed to keep local.
061   * @param ts timestamp
062   */
063  public Put(byte[] row, long ts) {
064    this(row, 0, row.length, ts);
065  }
066
067  /**
068   * We make a copy of the passed in row key to keep local.
069   * @param rowArray
070   * @param rowOffset
071   * @param rowLength
072   */
073  public Put(byte [] rowArray, int rowOffset, int rowLength) {
074    this(rowArray, rowOffset, rowLength, HConstants.LATEST_TIMESTAMP);
075  }
076
077  /**
078   * @param row row key; we make a copy of what we are passed to keep local.
079   * @param ts  timestamp
080   */
081  public Put(ByteBuffer row, long ts) {
082    if (ts < 0) {
083      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts);
084    }
085    checkRow(row);
086    this.row = new byte[row.remaining()];
087    row.get(this.row);
088    this.ts = ts;
089  }
090
091  /**
092   * @param row row key; we make a copy of what we are passed to keep local.
093   */
094  public Put(ByteBuffer row) {
095    this(row, HConstants.LATEST_TIMESTAMP);
096  }
097
098  /**
099   * We make a copy of the passed in row key to keep local.
100   * @param rowArray
101   * @param rowOffset
102   * @param rowLength
103   * @param ts
104   */
105  public Put(byte [] rowArray, int rowOffset, int rowLength, long ts) {
106    checkRow(rowArray, rowOffset, rowLength);
107    this.row = Bytes.copy(rowArray, rowOffset, rowLength);
108    this.ts = ts;
109    if (ts < 0) {
110      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts);
111    }
112  }
113
114  /**
115   * Create a Put operation for an immutable row key.
116   *
117   * @param row row key
118   * @param rowIsImmutable whether the input row is immutable.
119   *                       Set to true if the caller can guarantee that
120   *                       the row will not be changed for the Put duration.
121   */
122  public Put(byte [] row, boolean rowIsImmutable) {
123    this(row, HConstants.LATEST_TIMESTAMP, rowIsImmutable);
124  }
125
126  /**
127   * Create a Put operation for an immutable row key, using a given timestamp.
128   *
129   * @param row row key
130   * @param ts timestamp
131   * @param rowIsImmutable whether the input row is immutable.
132   *                       Set to true if the caller can guarantee that
133   *                       the row will not be changed for the Put duration.
134   */
135  public Put(byte[] row, long ts, boolean rowIsImmutable) {
136    // Check and set timestamp
137    if (ts < 0) {
138      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts);
139    }
140    this.ts = ts;
141
142    // Deal with row according to rowIsImmutable
143    checkRow(row);
144    if (rowIsImmutable) {  // Row is immutable
145      this.row = row;  // Do not make a local copy, but point to the provided byte array directly
146    } else {  // Row is not immutable
147      this.row = Bytes.copy(row, 0, row.length);  // Make a local copy
148    }
149  }
150
151  /**
152   * Copy constructor.  Creates a Put operation cloned from the specified Put.
153   * @param putToCopy put to copy
154   */
155  public Put(Put putToCopy) {
156    super(putToCopy);
157  }
158
159  /**
160   * Construct the Put with user defined data. NOTED:
161   * 1) all cells in the familyMap must have the Type.Put
162   * 2) the row of each cell must be same with passed row.
163   * @param row row. CAN'T be null
164   * @param ts timestamp
165   * @param familyMap the map to collect all cells internally. CAN'T be null
166   */
167  public Put(byte[] row, long ts, NavigableMap<byte [], List<Cell>> familyMap) {
168    super(row, ts, familyMap);
169  }
170
171  /**
172   * Add the specified column and value to this Put operation.
173   * @param family family name
174   * @param qualifier column qualifier
175   * @param value column value
176   * @return this
177   */
178  public Put addColumn(byte [] family, byte [] qualifier, byte [] value) {
179    return addColumn(family, qualifier, this.ts, value);
180  }
181
182  /**
183   * Add the specified column and value, with the specified timestamp as
184   * its version to this Put operation.
185   * @param family family name
186   * @param qualifier column qualifier
187   * @param ts version timestamp
188   * @param value column value
189   * @return this
190   */
191  public Put addColumn(byte [] family, byte [] qualifier, long ts, byte [] 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);
197    list.add(kv);
198    return this;
199  }
200
201  /**
202   * Add the specified column and value, with the specified timestamp as
203   * its version to this Put operation.
204   * @param family family name
205   * @param qualifier column qualifier
206   * @param ts version timestamp
207   * @param value column value
208   * @return this
209   */
210  public Put addColumn(byte[] family, ByteBuffer qualifier, long ts, ByteBuffer value) {
211    if (ts < 0) {
212      throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + ts);
213    }
214    List<Cell> list = getCellList(family);
215    KeyValue kv = createPutKeyValue(family, qualifier, ts, value, null);
216    list.add(kv);
217    return this;
218  }
219
220  /**
221   * Add the specified KeyValue to this Put operation.  Operation assumes that
222   * the passed KeyValue is immutable and its backing array will not be modified
223   * for the duration of this Put.
224   * @param cell individual cell
225   * @return this
226   * @throws java.io.IOException e
227   */
228  public Put add(Cell cell) throws IOException {
229    super.add(cell);
230    return this;
231  }
232
233  @Override
234  public Put setTimestamp(long timestamp) {
235    super.setTimestamp(timestamp);
236    return this;
237  }
238
239  @Override
240  public Put setAttribute(String name, byte[] value) {
241    return (Put) super.setAttribute(name, value);
242  }
243
244  @Override
245  public Put setId(String id) {
246    return (Put) super.setId(id);
247  }
248
249  @Override
250  public Put setDurability(Durability d) {
251    return (Put) super.setDurability(d);
252  }
253
254  @Override
255  public Put setClusterIds(List<UUID> clusterIds) {
256    return (Put) super.setClusterIds(clusterIds);
257  }
258
259  @Override
260  public Put setCellVisibility(CellVisibility expression) {
261    return (Put) super.setCellVisibility(expression);
262  }
263
264  @Override
265  public Put setACL(String user, Permission perms) {
266    return (Put) super.setACL(user, perms);
267  }
268
269  @Override
270  public Put setACL(Map<String, Permission> perms) {
271    return (Put) super.setACL(perms);
272  }
273
274  @Override
275  public Put setTTL(long ttl) {
276    return (Put) super.setTTL(ttl);
277  }
278
279  @Override
280  public Put setPriority(int priority) {
281    return (Put) super.setPriority(priority);
282  }
283
284  @Override
285  public CellBuilder getCellBuilder(CellBuilderType type) {
286    return getCellBuilder(type, Cell.Type.Put);
287  }
288
289}