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