1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.client;
22
23 import org.apache.hadoop.hbase.HConstants;
24 import org.apache.hadoop.hbase.KeyValue;
25 import org.apache.hadoop.hbase.util.Bytes;
26 import org.apache.hadoop.io.Writable;
27
28 import java.io.DataInput;
29 import java.io.DataOutput;
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Map;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class Delete extends Mutation
68 implements Writable, Comparable<Row> {
69 private static final byte DELETE_VERSION = (byte)3;
70
71
72 public Delete() {
73 this((byte [])null);
74 }
75
76
77
78
79
80
81
82
83
84 public Delete(byte [] row) {
85 this(row, HConstants.LATEST_TIMESTAMP);
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public Delete(byte [] row, long timestamp) {
101 this.row = row;
102 this.ts = timestamp;
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public Delete(byte [] row, long timestamp, RowLock rowLock) {
121 this.row = row;
122 this.ts = timestamp;
123 if (rowLock != null) {
124 this.lockId = rowLock.getLockId();
125 }
126 }
127
128
129
130
131 public Delete(final Delete d) {
132 this.row = d.getRow();
133 this.ts = d.getTimeStamp();
134 this.lockId = d.getLockId();
135 this.familyMap.putAll(d.getFamilyMap());
136 this.writeToWAL = d.writeToWAL;
137 }
138
139
140
141
142
143
144
145
146 public Delete addDeleteMarker(KeyValue kv) throws IOException {
147 if (!kv.isDelete()) {
148 throw new IOException("The recently added KeyValue is not of type "
149 + "delete. Rowkey: " + Bytes.toStringBinary(this.row));
150 }
151 if (Bytes.compareTo(this.row, 0, row.length, kv.getBuffer(),
152 kv.getRowOffset(), kv.getRowLength()) != 0) {
153 throw new IOException("The row in the recently added KeyValue "
154 + Bytes.toStringBinary(kv.getBuffer(), kv.getRowOffset(),
155 kv.getRowLength()) + " doesn't match the original one "
156 + Bytes.toStringBinary(this.row));
157 }
158 byte [] family = kv.getFamily();
159 List<KeyValue> list = familyMap.get(family);
160 if (list == null) {
161 list = new ArrayList<KeyValue>();
162 }
163 list.add(kv);
164 familyMap.put(family, list);
165 return this;
166 }
167
168
169
170
171
172
173
174
175
176 public Delete deleteFamily(byte [] family) {
177 this.deleteFamily(family, HConstants.LATEST_TIMESTAMP);
178 return this;
179 }
180
181
182
183
184
185
186
187
188
189
190
191 public Delete deleteFamily(byte [] family, long timestamp) {
192 List<KeyValue> list = familyMap.get(family);
193 if(list == null) {
194 list = new ArrayList<KeyValue>();
195 } else if(!list.isEmpty()) {
196 list.clear();
197 }
198 list.add(new KeyValue(row, family, null, timestamp, KeyValue.Type.DeleteFamily));
199 familyMap.put(family, list);
200 return this;
201 }
202
203
204
205
206
207
208
209 public Delete deleteColumns(byte [] family, byte [] qualifier) {
210 this.deleteColumns(family, qualifier, HConstants.LATEST_TIMESTAMP);
211 return this;
212 }
213
214
215
216
217
218
219
220
221
222 public Delete deleteColumns(byte [] family, byte [] qualifier, long timestamp) {
223 List<KeyValue> list = familyMap.get(family);
224 if (list == null) {
225 list = new ArrayList<KeyValue>();
226 }
227 list.add(new KeyValue(this.row, family, qualifier, timestamp,
228 KeyValue.Type.DeleteColumn));
229 familyMap.put(family, list);
230 return this;
231 }
232
233
234
235
236
237
238
239
240
241
242 public Delete deleteColumn(byte [] family, byte [] qualifier) {
243 this.deleteColumn(family, qualifier, HConstants.LATEST_TIMESTAMP);
244 return this;
245 }
246
247
248
249
250
251
252
253
254 public Delete deleteColumn(byte [] family, byte [] qualifier, long timestamp) {
255 List<KeyValue> list = familyMap.get(family);
256 if(list == null) {
257 list = new ArrayList<KeyValue>();
258 }
259 list.add(new KeyValue(
260 this.row, family, qualifier, timestamp, KeyValue.Type.Delete));
261 familyMap.put(family, list);
262 return this;
263 }
264
265
266
267
268
269
270 public void setTimestamp(long timestamp) {
271 this.ts = timestamp;
272 }
273
274 @Override
275 public Map<String, Object> toMap(int maxCols) {
276
277 Map<String, Object> map = super.toMap(maxCols);
278
279 map.put("ts", this.ts);
280 return map;
281 }
282
283
284 public void readFields(final DataInput in) throws IOException {
285 int version = in.readByte();
286 if (version > DELETE_VERSION) {
287 throw new IOException("version not supported");
288 }
289 this.row = Bytes.readByteArray(in);
290 this.ts = in.readLong();
291 this.lockId = in.readLong();
292 if (version > 2) {
293 this.writeToWAL = in.readBoolean();
294 }
295 this.familyMap.clear();
296 int numFamilies = in.readInt();
297 for(int i=0;i<numFamilies;i++) {
298 byte [] family = Bytes.readByteArray(in);
299 int numColumns = in.readInt();
300 List<KeyValue> list = new ArrayList<KeyValue>(numColumns);
301 for(int j=0;j<numColumns;j++) {
302 KeyValue kv = new KeyValue();
303 kv.readFields(in);
304 list.add(kv);
305 }
306 this.familyMap.put(family, list);
307 }
308 if (version > 1) {
309 readAttributes(in);
310 }
311 }
312
313 public void write(final DataOutput out) throws IOException {
314 out.writeByte(DELETE_VERSION);
315 Bytes.writeByteArray(out, this.row);
316 out.writeLong(this.ts);
317 out.writeLong(this.lockId);
318 out.writeBoolean(this.writeToWAL);
319 out.writeInt(familyMap.size());
320 for(Map.Entry<byte [], List<KeyValue>> entry : familyMap.entrySet()) {
321 Bytes.writeByteArray(out, entry.getKey());
322 List<KeyValue> list = entry.getValue();
323 out.writeInt(list.size());
324 for(KeyValue kv : list) {
325 kv.write(out);
326 }
327 }
328 writeAttributes(out);
329 }
330 }