1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.io.IOException;
22 import java.nio.ByteBuffer;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map.Entry;
26 import java.util.NavigableMap;
27
28 import org.apache.hadoop.classification.InterfaceAudience;
29 import org.apache.hadoop.classification.InterfaceStability;
30 import org.apache.hadoop.hbase.KeyValue.Type;
31 import org.apache.hadoop.hbase.util.ByteRange;
32 import org.apache.hadoop.hbase.util.Bytes;
33
34
35
36
37 @InterfaceAudience.Public
38 @InterfaceStability.Evolving
39 public final class CellUtil {
40
41
42
43 public static ByteRange fillRowRange(Cell cell, ByteRange range) {
44 return range.set(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
45 }
46
47 public static ByteRange fillFamilyRange(Cell cell, ByteRange range) {
48 return range.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
49 }
50
51 public static ByteRange fillQualifierRange(Cell cell, ByteRange range) {
52 return range.set(cell.getQualifierArray(), cell.getQualifierOffset(),
53 cell.getQualifierLength());
54 }
55
56
57
58
59 public static byte[] cloneRow(Cell cell){
60 byte[] output = new byte[cell.getRowLength()];
61 copyRowTo(cell, output, 0);
62 return output;
63 }
64
65 public static byte[] cloneFamily(Cell cell){
66 byte[] output = new byte[cell.getFamilyLength()];
67 copyFamilyTo(cell, output, 0);
68 return output;
69 }
70
71 public static byte[] cloneQualifier(Cell cell){
72 byte[] output = new byte[cell.getQualifierLength()];
73 copyQualifierTo(cell, output, 0);
74 return output;
75 }
76
77 public static byte[] cloneValue(Cell cell){
78 byte[] output = new byte[cell.getValueLength()];
79 copyValueTo(cell, output, 0);
80 return output;
81 }
82
83
84
85
86 public static int copyRowTo(Cell cell, byte[] destination, int destinationOffset) {
87 System.arraycopy(cell.getRowArray(), cell.getRowOffset(), destination, destinationOffset,
88 cell.getRowLength());
89 return destinationOffset + cell.getRowLength();
90 }
91
92 public static int copyFamilyTo(Cell cell, byte[] destination, int destinationOffset) {
93 System.arraycopy(cell.getFamilyArray(), cell.getFamilyOffset(), destination, destinationOffset,
94 cell.getFamilyLength());
95 return destinationOffset + cell.getFamilyLength();
96 }
97
98 public static int copyQualifierTo(Cell cell, byte[] destination, int destinationOffset) {
99 System.arraycopy(cell.getQualifierArray(), cell.getQualifierOffset(), destination,
100 destinationOffset, cell.getQualifierLength());
101 return destinationOffset + cell.getQualifierLength();
102 }
103
104 public static int copyValueTo(Cell cell, byte[] destination, int destinationOffset) {
105 System.arraycopy(cell.getValueArray(), cell.getValueOffset(), destination, destinationOffset,
106 cell.getValueLength());
107 return destinationOffset + cell.getValueLength();
108 }
109
110
111
112
113 public static byte getRowByte(Cell cell, int index) {
114 return cell.getRowArray()[cell.getRowOffset() + index];
115 }
116
117 public static ByteBuffer getValueBufferShallowCopy(Cell cell) {
118 ByteBuffer buffer = ByteBuffer.wrap(cell.getValueArray(), cell.getValueOffset(),
119 cell.getValueLength());
120 return buffer;
121 }
122
123 public static ByteBuffer getQualifierBufferShallowCopy(Cell cell) {
124 ByteBuffer buffer = ByteBuffer.wrap(cell.getQualifierArray(), cell.getQualifierOffset(),
125 cell.getQualifierLength());
126 return buffer;
127 }
128
129 public static Cell createCell(final byte [] row, final byte [] family, final byte [] qualifier,
130 final long timestamp, final byte type, final byte [] value) {
131
132
133
134 return new KeyValue(row, family, qualifier, timestamp,
135 KeyValue.Type.codeToType(type), value);
136 }
137
138
139
140
141
142 public static CellScanner createCellScanner(final List<? extends CellScannable> cellScannerables) {
143 return new CellScanner() {
144 private final Iterator<? extends CellScannable> iterator = cellScannerables.iterator();
145 private CellScanner cellScanner = null;
146
147 @Override
148 public Cell current() {
149 return this.cellScanner != null? this.cellScanner.current(): null;
150 }
151
152 @Override
153 public boolean advance() throws IOException {
154 if (this.cellScanner == null) {
155 if (!this.iterator.hasNext()) return false;
156 this.cellScanner = this.iterator.next().cellScanner();
157 }
158 if (this.cellScanner.advance()) return true;
159 this.cellScanner = null;
160 return advance();
161 }
162 };
163 }
164
165
166
167
168
169 public static CellScanner createCellScanner(final Iterable<Cell> cellIterable) {
170 if (cellIterable == null) return null;
171 return createCellScanner(cellIterable.iterator());
172 }
173
174
175
176
177
178
179 public static CellScanner createCellScanner(final Iterator<Cell> cells) {
180 if (cells == null) return null;
181 return new CellScanner() {
182 private final Iterator<Cell> iterator = cells;
183 private Cell current = null;
184
185 @Override
186 public Cell current() {
187 return this.current;
188 }
189
190 @Override
191 public boolean advance() {
192 boolean hasNext = this.iterator.hasNext();
193 this.current = hasNext? this.iterator.next(): null;
194 return hasNext;
195 }
196 };
197 }
198
199
200
201
202
203 public static CellScanner createCellScanner(final Cell[] cellArray) {
204 return new CellScanner() {
205 private final Cell [] cells = cellArray;
206 private int index = -1;
207
208 @Override
209 public Cell current() {
210 if (cells == null) return null;
211 return (index < 0)? null: this.cells[index];
212 }
213
214 @Override
215 public boolean advance() {
216 if (cells == null) return false;
217 return ++index < this.cells.length;
218 }
219 };
220 }
221
222
223
224
225
226
227
228 public static CellScanner createCellScanner(final NavigableMap<byte [],
229 List<Cell>> map) {
230 return new CellScanner() {
231 private final Iterator<Entry<byte[], List<Cell>>> entries =
232 map.entrySet().iterator();
233 private Iterator<Cell> currentIterator = null;
234 private Cell currentCell;
235
236 @Override
237 public Cell current() {
238 return this.currentCell;
239 }
240
241 @Override
242 public boolean advance() {
243 if (this.currentIterator == null) {
244 if (!this.entries.hasNext()) return false;
245 this.currentIterator = this.entries.next().getValue().iterator();
246 }
247 if (this.currentIterator.hasNext()) {
248 this.currentCell = this.currentIterator.next();
249 return true;
250 }
251 this.currentCell = null;
252 this.currentIterator = null;
253 return advance();
254 }
255 };
256 }
257
258
259
260
261
262
263 public static boolean matchingRow(final Cell left, final Cell right) {
264 return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(),
265 right.getRowArray(), right.getRowOffset(), right.getRowLength());
266 }
267
268 public static boolean matchingRow(final Cell left, final byte[] buf) {
269 return Bytes.equals(left.getRowArray(), left.getRowOffset(), left.getRowLength(),
270 buf, 0, buf.length);
271 }
272
273 public static boolean matchingFamily(final Cell left, final Cell right) {
274 return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(),
275 right.getFamilyArray(), right.getFamilyOffset(), right.getFamilyLength());
276 }
277
278 public static boolean matchingFamily(final Cell left, final byte[] buf) {
279 return Bytes.equals(left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(),
280 buf, 0, buf.length);
281 }
282
283 public static boolean matchingQualifier(final Cell left, final Cell right) {
284 return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), left.getQualifierLength(),
285 right.getQualifierArray(), right.getQualifierOffset(), right.getQualifierLength());
286 }
287
288 public static boolean matchingQualifier(final Cell left, final byte[] buf) {
289 return Bytes.equals(left.getQualifierArray(), left.getQualifierOffset(), left.getQualifierLength(),
290 buf, 0, buf.length);
291 }
292
293
294 public static boolean matchingValue(final Cell left, final Cell right) {
295 return Bytes.equals(left.getValueArray(), left.getValueOffset(), left.getValueLength(),
296 right.getValueArray(), right.getValueOffset(), right.getValueLength());
297 }
298
299 public static boolean matchingValue(final Cell left, final byte[] buf) {
300 return Bytes.equals(left.getValueArray(), left.getValueOffset(), left.getValueLength(),
301 buf, 0, buf.length);
302 }
303
304
305
306
307
308 public static boolean isDelete(final Cell cell) {
309 return KeyValue.isDelete(cell.getTypeByte());
310 }
311
312 public static boolean isDeleteFamily(final Cell cell) {
313 return cell.getTypeByte() == Type.DeleteFamily.getCode();
314 }
315
316
317
318
319
320 public static int estimatedSizeOf(final Cell cell) {
321
322 if (cell instanceof KeyValue) {
323 return ((KeyValue)cell).getLength() + Bytes.SIZEOF_INT;
324 }
325
326
327 return cell.getRowLength() + cell.getFamilyLength() +
328 cell.getQualifierLength() +
329 cell.getValueLength() +
330
331
332 KeyValue.KEY_INFRASTRUCTURE_SIZE +
333
334 Bytes.SIZEOF_INT;
335 }
336 }