3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 package org
.apache
.hadoop
.hbase
.client
;
22 import java
.io
.IOException
;
23 import java
.util
.ArrayList
;
24 import java
.util
.List
;
26 import java
.util
.NavigableMap
;
27 import java
.util
.UUID
;
29 import org
.apache
.hadoop
.hbase
.Cell
;
30 import org
.apache
.hadoop
.hbase
.CellUtil
;
31 import org
.apache
.hadoop
.hbase
.HConstants
;
32 import org
.apache
.hadoop
.hbase
.KeyValue
;
33 import org
.apache
.hadoop
.hbase
.classification
.InterfaceAudience
;
34 import org
.apache
.hadoop
.hbase
.security
.access
.Permission
;
35 import org
.apache
.hadoop
.hbase
.security
.visibility
.CellVisibility
;
36 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
39 * Used to perform Delete operations on a single row.
41 * To delete an entire row, instantiate a Delete object with the row
42 * to delete. To further define the scope of what to delete, perform
43 * additional methods as outlined below.
45 * To delete specific families, execute {@link #addFamily(byte[]) deleteFamily}
46 * for each family to delete.
48 * To delete multiple versions of specific columns, execute
49 * {@link #addColumns(byte[], byte[]) deleteColumns}
50 * for each column to delete.
52 * To delete specific versions of specific columns, execute
53 * {@link #addColumn(byte[], byte[], long) deleteColumn}
54 * for each column version to delete.
56 * Specifying timestamps, deleteFamily and deleteColumns will delete all
57 * versions with a timestamp less than or equal to that passed. If no
58 * timestamp is specified, an entry is added with a timestamp of 'now'
59 * where 'now' is the servers's System.currentTimeMillis().
60 * Specifying a timestamp to the deleteColumn method will
61 * delete versions only with a timestamp equal to that specified.
62 * If no timestamp is passed to deleteColumn, internally, it figures the
63 * most recent cell's timestamp and adds a delete at that timestamp; i.e.
64 * it deletes the most recently added cell.
65 * <p>The timestamp passed to the constructor is used ONLY for delete of
66 * rows. For anything less -- a deleteColumn, deleteColumns or
67 * deleteFamily -- then you need to use the method overrides that take a
68 * timestamp. The constructor timestamp is not referenced.
70 @InterfaceAudience.Public
71 public class Delete
extends Mutation
implements Comparable
<Row
> {
73 * Create a Delete operation for the specified row.
75 * If no further operations are done, this will delete everything
76 * associated with the specified row (all versions of all columns in all
77 * families), with timestamp from current point in time to the past.
78 * Cells defining timestamp for a future point in time
79 * (timestamp > current time) will not be deleted.
82 public Delete(byte [] row
) {
83 this(row
, HConstants
.LATEST_TIMESTAMP
);
87 * Create a Delete operation for the specified row and timestamp.<p>
89 * If no further operations are done, this will delete all columns in all
90 * families of the specified row with a timestamp less than or equal to the
91 * specified timestamp.<p>
93 * This timestamp is ONLY used for a delete row operation. If specifying
94 * families or columns, you must specify each timestamp individually.
96 * @param timestamp maximum version timestamp (only for delete row)
98 public Delete(byte [] row
, long timestamp
) {
99 this(row
, 0, row
.length
, timestamp
);
103 * Create a Delete operation for the specified row and timestamp.<p>
105 * If no further operations are done, this will delete all columns in all
106 * families of the specified row with a timestamp less than or equal to the
107 * specified timestamp.<p>
109 * This timestamp is ONLY used for a delete row operation. If specifying
110 * families or columns, you must specify each timestamp individually.
111 * @param row We make a local copy of this passed in row.
115 public Delete(final byte[] row
, final int rowOffset
, final int rowLength
) {
116 this(row
, rowOffset
, rowLength
, HConstants
.LATEST_TIMESTAMP
);
120 * Create a Delete operation for the specified row and timestamp.<p>
122 * If no further operations are done, this will delete all columns in all
123 * families of the specified row with a timestamp less than or equal to the
124 * specified timestamp.<p>
126 * This timestamp is ONLY used for a delete row operation. If specifying
127 * families or columns, you must specify each timestamp individually.
128 * @param row We make a local copy of this passed in row.
131 * @param timestamp maximum version timestamp (only for delete row)
133 public Delete(final byte[] row
, final int rowOffset
, final int rowLength
, long timestamp
) {
134 checkRow(row
, rowOffset
, rowLength
);
135 this.row
= Bytes
.copy(row
, rowOffset
, rowLength
);
136 setTimestamp(timestamp
);
140 * @param d Delete to clone.
142 public Delete(final Delete d
) {
143 this.row
= d
.getRow();
144 this.ts
= d
.getTimeStamp();
145 this.familyMap
.putAll(d
.getFamilyCellMap());
146 this.durability
= d
.durability
;
147 for (Map
.Entry
<String
, byte[]> entry
: d
.getAttributesMap().entrySet()) {
148 this.setAttribute(entry
.getKey(), entry
.getValue());
154 * Add an existing delete marker to this Delete object.
155 * @param kv An existing KeyValue of type "delete".
156 * @return this for invocation chaining
157 * @throws IOException
159 @SuppressWarnings("unchecked")
160 public Delete
addDeleteMarker(Cell kv
) throws IOException
{
161 // TODO: Deprecate and rename 'add' so it matches how we add KVs to Puts.
162 if (!CellUtil
.isDelete(kv
)) {
163 throw new IOException("The recently added KeyValue is not of type "
164 + "delete. Rowkey: " + Bytes
.toStringBinary(this.row
));
166 if (!CellUtil
.matchingRow(kv
, this.row
)) {
167 throw new WrongRowIOException("The row in " + kv
.toString() +
168 " doesn't match the original one " + Bytes
.toStringBinary(this.row
));
170 byte [] family
= CellUtil
.cloneFamily(kv
);
171 List
<Cell
> list
= familyMap
.get(family
);
173 list
= new ArrayList
<>(1);
176 familyMap
.put(family
, list
);
182 * Delete all versions of all columns of the specified family.
184 * Overrides previous calls to deleteColumn and deleteColumns for the
186 * @param family family name
187 * @return this for invocation chaining
189 public Delete
addFamily(final byte [] family
) {
190 this.addFamily(family
, this.ts
);
195 * Delete all columns of the specified family with a timestamp less than
196 * or equal to the specified timestamp.
198 * Overrides previous calls to deleteColumn and deleteColumns for the
200 * @param family family name
201 * @param timestamp maximum version timestamp
202 * @return this for invocation chaining
204 public Delete
addFamily(final byte [] family
, final long timestamp
) {
206 throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp
);
208 List
<Cell
> list
= familyMap
.get(family
);
210 list
= new ArrayList
<>(1);
211 } else if(!list
.isEmpty()) {
214 KeyValue kv
= new KeyValue(row
, family
, null, timestamp
, KeyValue
.Type
.DeleteFamily
);
216 familyMap
.put(family
, list
);
221 * Delete all columns of the specified family with a timestamp equal to
222 * the specified timestamp.
223 * @param family family name
224 * @param timestamp version timestamp
225 * @return this for invocation chaining
227 public Delete
addFamilyVersion(final byte [] family
, final long timestamp
) {
228 List
<Cell
> list
= familyMap
.get(family
);
230 list
= new ArrayList
<>(1);
232 list
.add(new KeyValue(row
, family
, null, timestamp
,
233 KeyValue
.Type
.DeleteFamilyVersion
));
234 familyMap
.put(family
, list
);
239 * Delete all versions of the specified column.
240 * @param family family name
241 * @param qualifier column qualifier
242 * @return this for invocation chaining
244 public Delete
addColumns(final byte [] family
, final byte [] qualifier
) {
245 addColumns(family
, qualifier
, this.ts
);
250 * Delete all versions of the specified column with a timestamp less than
251 * or equal to the specified timestamp.
252 * @param family family name
253 * @param qualifier column qualifier
254 * @param timestamp maximum version timestamp
255 * @return this for invocation chaining
257 public Delete
addColumns(final byte [] family
, final byte [] qualifier
, final long timestamp
) {
259 throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp
);
261 List
<Cell
> list
= familyMap
.get(family
);
263 list
= new ArrayList
<>(1);
265 list
.add(new KeyValue(this.row
, family
, qualifier
, timestamp
,
266 KeyValue
.Type
.DeleteColumn
));
267 familyMap
.put(family
, list
);
272 * Delete the latest version of the specified column.
273 * This is an expensive call in that on the server-side, it first does a
274 * get to find the latest versions timestamp. Then it adds a delete using
275 * the fetched cells timestamp.
276 * @param family family name
277 * @param qualifier column qualifier
278 * @return this for invocation chaining
280 public Delete
addColumn(final byte [] family
, final byte [] qualifier
) {
281 this.addColumn(family
, qualifier
, this.ts
);
286 * Delete the specified version of the specified column.
287 * @param family family name
288 * @param qualifier column qualifier
289 * @param timestamp version timestamp
290 * @return this for invocation chaining
292 public Delete
addColumn(byte [] family
, byte [] qualifier
, long timestamp
) {
294 throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp
);
296 List
<Cell
> list
= familyMap
.get(family
);
298 list
= new ArrayList
<>(1);
300 KeyValue kv
= new KeyValue(this.row
, family
, qualifier
, timestamp
, KeyValue
.Type
.Delete
);
302 familyMap
.put(family
, list
);
307 * Set the timestamp of the delete.
311 public Delete
setTimestamp(long timestamp
) {
313 throw new IllegalArgumentException("Timestamp cannot be negative. ts=" + timestamp
);
320 public Map
<String
, Object
> toMap(int maxCols
) {
321 // we start with the fingerprint map and build on top of it.
322 Map
<String
, Object
> map
= super.toMap(maxCols
);
323 // why is put not doing this?
324 map
.put("ts", this.ts
);
329 public Delete
setAttribute(String name
, byte[] value
) {
330 return (Delete
) super.setAttribute(name
, value
);
334 public Delete
setId(String id
) {
335 return (Delete
) super.setId(id
);
339 public Delete
setDurability(Durability d
) {
340 return (Delete
) super.setDurability(d
);
344 public Delete
setFamilyCellMap(NavigableMap
<byte[], List
<Cell
>> map
) {
345 return (Delete
) super.setFamilyCellMap(map
);
349 public Delete
setClusterIds(List
<UUID
> clusterIds
) {
350 return (Delete
) super.setClusterIds(clusterIds
);
354 public Delete
setCellVisibility(CellVisibility expression
) {
355 return (Delete
) super.setCellVisibility(expression
);
359 public Delete
setACL(String user
, Permission perms
) {
360 return (Delete
) super.setACL(user
, perms
);
364 public Delete
setACL(Map
<String
, Permission
> perms
) {
365 return (Delete
) super.setACL(perms
);
369 public Delete
setTTL(long ttl
) {
370 throw new UnsupportedOperationException("Setting TTLs on Deletes is not supported");