1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import static org.apache.hadoop.hbase.util.Bytes.len;
23
24 import java.io.DataInput;
25 import java.io.DataOutput;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.io.OutputStream;
29 import java.nio.ByteBuffer;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Comparator;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.hadoop.classification.InterfaceAudience;
40 import org.apache.hadoop.hbase.io.HeapSize;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.hbase.util.ClassSize;
43 import org.apache.hadoop.io.IOUtils;
44 import org.apache.hadoop.io.RawComparator;
45
46 import com.google.common.primitives.Longs;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 @InterfaceAudience.Private
81 public class KeyValue implements Cell, HeapSize, Cloneable {
82 private static final ArrayList<Tag> EMPTY_ARRAY_LIST = new ArrayList<Tag>();
83
84 static final Log LOG = LogFactory.getLog(KeyValue.class);
85
86
87
88
89 public static final char COLUMN_FAMILY_DELIMITER = ':';
90
91 public static final byte[] COLUMN_FAMILY_DELIM_ARRAY =
92 new byte[]{COLUMN_FAMILY_DELIMITER};
93
94
95
96
97
98 public static final KVComparator COMPARATOR = new KVComparator();
99
100
101
102
103 public static final KVComparator META_COMPARATOR = new MetaComparator();
104
105
106
107
108 public static final KVComparator RAW_COMPARATOR = new RawBytesComparator();
109
110
111 public static final int KEY_LENGTH_SIZE = Bytes.SIZEOF_INT;
112
113
114 public static final int TYPE_SIZE = Bytes.SIZEOF_BYTE;
115
116
117 public static final int ROW_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
118
119
120 public static final int FAMILY_LENGTH_SIZE = Bytes.SIZEOF_BYTE;
121
122
123 public static final int TIMESTAMP_SIZE = Bytes.SIZEOF_LONG;
124
125
126 public static final int TIMESTAMP_TYPE_SIZE = TIMESTAMP_SIZE + TYPE_SIZE;
127
128
129 public static final int KEY_INFRASTRUCTURE_SIZE = ROW_LENGTH_SIZE
130 + FAMILY_LENGTH_SIZE + TIMESTAMP_TYPE_SIZE;
131
132
133
134 public static final int ROW_OFFSET =
135 Bytes.SIZEOF_INT
136 Bytes.SIZEOF_INT
137
138
139 public static final int KEYVALUE_INFRASTRUCTURE_SIZE = ROW_OFFSET;
140
141
142 public static final int TAGS_LENGTH_SIZE = Bytes.SIZEOF_SHORT;
143
144 public static final int KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE = ROW_OFFSET + TAGS_LENGTH_SIZE;
145
146
147
148
149
150
151
152
153
154
155
156
157
158 public static long getKeyValueDataStructureSize(int rlength,
159 int flength, int qlength, int vlength) {
160 return KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE
161 + getKeyDataStructureSize(rlength, flength, qlength) + vlength;
162 }
163
164
165
166
167
168
169
170
171
172
173
174
175
176 public static long getKeyValueDataStructureSize(int rlength, int flength, int qlength,
177 int vlength, int tagsLength) {
178 if (tagsLength == 0) {
179 return getKeyValueDataStructureSize(rlength, flength, qlength, vlength);
180 }
181 return KeyValue.KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE
182 + getKeyDataStructureSize(rlength, flength, qlength) + vlength + tagsLength;
183 }
184
185
186
187
188
189
190
191
192
193
194
195 public static long getKeyValueDataStructureSize(int klength, int vlength, int tagsLength) {
196 if (tagsLength == 0) {
197 return KeyValue.KEYVALUE_INFRASTRUCTURE_SIZE + klength + vlength;
198 }
199 return KeyValue.KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE + klength + vlength + tagsLength;
200 }
201
202
203
204
205
206
207
208
209
210
211
212 public static long getKeyDataStructureSize(int rlength, int flength, int qlength) {
213 return KeyValue.KEY_INFRASTRUCTURE_SIZE + rlength + flength + qlength;
214 }
215
216
217
218
219
220
221 public static enum Type {
222 Minimum((byte)0),
223 Put((byte)4),
224
225 Delete((byte)8),
226 DeleteFamilyVersion((byte)10),
227 DeleteColumn((byte)12),
228 DeleteFamily((byte)14),
229
230
231 Maximum((byte)255);
232
233 private final byte code;
234
235 Type(final byte c) {
236 this.code = c;
237 }
238
239 public byte getCode() {
240 return this.code;
241 }
242
243
244
245
246
247
248
249 public static Type codeToType(final byte b) {
250 for (Type t : Type.values()) {
251 if (t.getCode() == b) {
252 return t;
253 }
254 }
255 throw new RuntimeException("Unknown code " + b);
256 }
257 }
258
259
260
261
262
263
264 public static final KeyValue LOWESTKEY =
265 new KeyValue(HConstants.EMPTY_BYTE_ARRAY, HConstants.LATEST_TIMESTAMP);
266
267
268
269 private byte [] bytes = null;
270 private int offset = 0;
271 private int length = 0;
272
273
274
275
276
277
278 public static boolean isDelete(byte t) {
279 return Type.Delete.getCode() <= t && t <= Type.DeleteFamily.getCode();
280 }
281
282
283
284
285 @Override
286 public long getMvccVersion() {
287 return mvcc;
288 }
289
290 public void setMvccVersion(long mvccVersion){
291 this.mvcc = mvccVersion;
292 }
293
294
295 private long mvcc = 0;
296
297
298
299
300
301 public KeyValue() {}
302
303
304
305
306
307
308 public KeyValue(final byte [] bytes) {
309 this(bytes, 0);
310 }
311
312
313
314
315
316
317
318
319 public KeyValue(final byte [] bytes, final int offset) {
320 this(bytes, offset, getLength(bytes, offset));
321 }
322
323
324
325
326
327
328
329
330 public KeyValue(final byte [] bytes, final int offset, final int length) {
331 this.bytes = bytes;
332 this.offset = offset;
333 this.length = length;
334 }
335
336
337
338
339
340
341
342
343
344
345 public KeyValue(final byte[] bytes, final int offset, final int length, long ts) {
346 this(bytes, offset, length, null, 0, 0, null, 0, 0, ts, Type.Maximum, null, 0, 0, null);
347 }
348
349
350
351
352
353
354
355
356
357 public KeyValue(final byte [] row, final long timestamp) {
358 this(row, null, null, timestamp, Type.Maximum, null);
359 }
360
361
362
363
364
365
366 public KeyValue(final byte [] row, final long timestamp, Type type) {
367 this(row, null, null, timestamp, type, null);
368 }
369
370
371
372
373
374
375
376
377 public KeyValue(final byte [] row, final byte [] family,
378 final byte [] qualifier) {
379 this(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Maximum);
380 }
381
382
383
384
385
386
387
388 public KeyValue(final byte [] row, final byte [] family,
389 final byte [] qualifier, final byte [] value) {
390 this(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Put, value);
391 }
392
393
394
395
396
397
398
399
400
401
402 public KeyValue(final byte[] row, final byte[] family,
403 final byte[] qualifier, final long timestamp, Type type) {
404 this(row, family, qualifier, timestamp, type, null);
405 }
406
407
408
409
410
411
412
413
414
415
416 public KeyValue(final byte[] row, final byte[] family,
417 final byte[] qualifier, final long timestamp, final byte[] value) {
418 this(row, family, qualifier, timestamp, Type.Put, value);
419 }
420
421
422
423
424
425
426
427
428
429
430
431 public KeyValue(final byte[] row, final byte[] family,
432 final byte[] qualifier, final long timestamp, final byte[] value,
433 final Tag[] tags) {
434 this(row, family, qualifier, timestamp, value, tags != null ? Arrays.asList(tags) : null);
435 }
436
437
438
439
440
441
442
443
444
445
446
447 public KeyValue(final byte[] row, final byte[] family,
448 final byte[] qualifier, final long timestamp, final byte[] value,
449 final List<Tag> tags) {
450 this(row, 0, row==null ? 0 : row.length,
451 family, 0, family==null ? 0 : family.length,
452 qualifier, 0, qualifier==null ? 0 : qualifier.length,
453 timestamp, Type.Put,
454 value, 0, value==null ? 0 : value.length, tags);
455 }
456
457
458
459
460
461
462
463
464
465
466
467 public KeyValue(final byte[] row, final byte[] family,
468 final byte[] qualifier, final long timestamp, Type type,
469 final byte[] value) {
470 this(row, 0, len(row), family, 0, len(family), qualifier, 0, len(qualifier),
471 timestamp, type, value, 0, len(value));
472 }
473
474
475
476
477
478
479
480
481
482
483
484
485
486 public KeyValue(final byte[] row, final byte[] family,
487 final byte[] qualifier, final long timestamp, Type type,
488 final byte[] value, final List<Tag> tags) {
489 this(row, family, qualifier, 0, qualifier==null ? 0 : qualifier.length,
490 timestamp, type, value, 0, value==null ? 0 : value.length, tags);
491 }
492
493
494
495
496
497
498
499
500
501
502
503 public KeyValue(final byte[] row, final byte[] family,
504 final byte[] qualifier, final long timestamp, Type type,
505 final byte[] value, final byte[] tags) {
506 this(row, family, qualifier, 0, qualifier==null ? 0 : qualifier.length,
507 timestamp, type, value, 0, value==null ? 0 : value.length, tags);
508 }
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524 public KeyValue(byte [] row, byte [] family,
525 byte [] qualifier, int qoffset, int qlength, long timestamp, Type type,
526 byte [] value, int voffset, int vlength, List<Tag> tags) {
527 this(row, 0, row==null ? 0 : row.length,
528 family, 0, family==null ? 0 : family.length,
529 qualifier, qoffset, qlength, timestamp, type,
530 value, voffset, vlength, tags);
531 }
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546 public KeyValue(byte [] row, byte [] family,
547 byte [] qualifier, int qoffset, int qlength, long timestamp, Type type,
548 byte [] value, int voffset, int vlength, byte[] tags) {
549 this(row, 0, row==null ? 0 : row.length,
550 family, 0, family==null ? 0 : family.length,
551 qualifier, qoffset, qlength, timestamp, type,
552 value, voffset, vlength, tags, 0, tags==null ? 0 : tags.length);
553 }
554
555
556
557
558
559
560
561
562 public KeyValue(final byte [] row, final int roffset, final int rlength,
563 final byte [] family, final int foffset, final int flength,
564 final byte [] qualifier, final int qoffset, final int qlength,
565 final long timestamp, final Type type,
566 final byte [] value, final int voffset, final int vlength) {
567 this(row, roffset, rlength, family, foffset, flength, qualifier, qoffset,
568 qlength, timestamp, type, value, voffset, vlength, null);
569 }
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 public KeyValue(byte [] buffer, final int boffset,
598 final byte [] row, final int roffset, final int rlength,
599 final byte [] family, final int foffset, final int flength,
600 final byte [] qualifier, final int qoffset, final int qlength,
601 final long timestamp, final Type type,
602 final byte [] value, final int voffset, final int vlength,
603 final Tag[] tags) {
604 this.bytes = buffer;
605 this.length = writeByteArray(buffer, boffset,
606 row, roffset, rlength,
607 family, foffset, flength, qualifier, qoffset, qlength,
608 timestamp, type, value, voffset, vlength, tags);
609 this.offset = boffset;
610 }
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633 public KeyValue(final byte [] row, final int roffset, final int rlength,
634 final byte [] family, final int foffset, final int flength,
635 final byte [] qualifier, final int qoffset, final int qlength,
636 final long timestamp, final Type type,
637 final byte [] value, final int voffset, final int vlength,
638 final List<Tag> tags) {
639 this.bytes = createByteArray(row, roffset, rlength,
640 family, foffset, flength, qualifier, qoffset, qlength,
641 timestamp, type, value, voffset, vlength, tags);
642 this.length = bytes.length;
643 this.offset = 0;
644 }
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663 public KeyValue(final byte [] row, final int roffset, final int rlength,
664 final byte [] family, final int foffset, final int flength,
665 final byte [] qualifier, final int qoffset, final int qlength,
666 final long timestamp, final Type type,
667 final byte [] value, final int voffset, final int vlength,
668 final byte[] tags, final int tagsOffset, final int tagsLength) {
669 this.bytes = createByteArray(row, roffset, rlength,
670 family, foffset, flength, qualifier, qoffset, qlength,
671 timestamp, type, value, voffset, vlength, tags, tagsOffset, tagsLength);
672 this.length = bytes.length;
673 this.offset = 0;
674 }
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689 public KeyValue(final int rlength,
690 final int flength,
691 final int qlength,
692 final long timestamp, final Type type,
693 final int vlength) {
694 this(rlength, flength, qlength, timestamp, type, vlength, 0);
695 }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711 public KeyValue(final int rlength,
712 final int flength,
713 final int qlength,
714 final long timestamp, final Type type,
715 final int vlength, final int tagsLength) {
716 this.bytes = createEmptyByteArray(rlength, flength, qlength, timestamp, type, vlength,
717 tagsLength);
718 this.length = bytes.length;
719 this.offset = 0;
720 }
721
722
723 public KeyValue(byte[] row, int roffset, int rlength,
724 byte[] family, int foffset, int flength,
725 ByteBuffer qualifier, long ts, Type type, ByteBuffer value, List<Tag> tags) {
726 this.bytes = createByteArray(row, roffset, rlength, family, foffset, flength,
727 qualifier, 0, qualifier == null ? 0 : qualifier.remaining(), ts, type,
728 value, 0, value == null ? 0 : value.remaining(), tags);
729 this.length = bytes.length;
730 this.offset = 0;
731 }
732
733 public KeyValue(Cell c) {
734 this(c.getRowArray(), c.getRowOffset(), (int)c.getRowLength(),
735 c.getFamilyArray(), c.getFamilyOffset(), (int)c.getFamilyLength(),
736 c.getQualifierArray(), c.getQualifierOffset(), (int) c.getQualifierLength(),
737 c.getTimestamp(), Type.codeToType(c.getTypeByte()), c.getValueArray(), c.getValueOffset(),
738 c.getValueLength(), c.getTagsArray(), c.getTagsOffset(), c.getTagsLength());
739 }
740
741
742
743
744
745
746
747
748
749
750
751
752 private static byte[] createEmptyByteArray(final int rlength, int flength,
753 int qlength, final long timestamp, final Type type, int vlength, int tagsLength) {
754 if (rlength > Short.MAX_VALUE) {
755 throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
756 }
757 if (flength > Byte.MAX_VALUE) {
758 throw new IllegalArgumentException("Family > " + Byte.MAX_VALUE);
759 }
760
761 if (qlength > Integer.MAX_VALUE - rlength - flength) {
762 throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
763 }
764 checkForTagsLength(tagsLength);
765
766 long longkeylength = getKeyDataStructureSize(rlength, flength, qlength);
767 if (longkeylength > Integer.MAX_VALUE) {
768 throw new IllegalArgumentException("keylength " + longkeylength + " > " +
769 Integer.MAX_VALUE);
770 }
771 int keylength = (int)longkeylength;
772
773 if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) {
774 throw new IllegalArgumentException("Valuer > " +
775 HConstants.MAXIMUM_VALUE_LENGTH);
776 }
777
778
779 byte[] bytes= new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
780 tagsLength)];
781
782 int pos = 0;
783 pos = Bytes.putInt(bytes, pos, keylength);
784 pos = Bytes.putInt(bytes, pos, vlength);
785 pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
786 pos += rlength;
787 pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
788 pos += flength + qlength;
789 pos = Bytes.putLong(bytes, pos, timestamp);
790 pos = Bytes.putByte(bytes, pos, type.getCode());
791 pos += vlength;
792 if (tagsLength > 0) {
793 pos = Bytes.putShort(bytes, pos, (short)(tagsLength & 0x0000ffff));
794 }
795 return bytes;
796 }
797
798
799
800
801
802
803
804
805
806
807
808
809
810 private static void checkParameters(final byte [] row, final int rlength,
811 final byte [] family, int flength, int qlength, int vlength)
812 throws IllegalArgumentException {
813 if (rlength > Short.MAX_VALUE) {
814 throw new IllegalArgumentException("Row > " + Short.MAX_VALUE);
815 }
816 if (row == null) {
817 throw new IllegalArgumentException("Row is null");
818 }
819
820 flength = family == null ? 0 : flength;
821 if (flength > Byte.MAX_VALUE) {
822 throw new IllegalArgumentException("Family > " + Byte.MAX_VALUE);
823 }
824
825 if (qlength > Integer.MAX_VALUE - rlength - flength) {
826 throw new IllegalArgumentException("Qualifier > " + Integer.MAX_VALUE);
827 }
828
829 long longKeyLength = getKeyDataStructureSize(rlength, flength, qlength);
830 if (longKeyLength > Integer.MAX_VALUE) {
831 throw new IllegalArgumentException("keylength " + longKeyLength + " > " +
832 Integer.MAX_VALUE);
833 }
834
835 if (vlength > HConstants.MAXIMUM_VALUE_LENGTH) {
836 throw new IllegalArgumentException("Value length " + vlength + " > " +
837 HConstants.MAXIMUM_VALUE_LENGTH);
838 }
839 }
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866 private static int writeByteArray(byte [] buffer, final int boffset,
867 final byte [] row, final int roffset, final int rlength,
868 final byte [] family, final int foffset, int flength,
869 final byte [] qualifier, final int qoffset, int qlength,
870 final long timestamp, final Type type,
871 final byte [] value, final int voffset, int vlength, Tag[] tags) {
872
873 checkParameters(row, rlength, family, flength, qlength, vlength);
874
875
876 int tagsLength = 0;
877 if (tags != null && tags.length > 0) {
878 for (Tag t: tags) {
879 tagsLength += t.getLength();
880 }
881 }
882 checkForTagsLength(tagsLength);
883 int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
884 int keyValueLength = (int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
885 tagsLength);
886 if (keyValueLength > buffer.length - boffset) {
887 throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +
888 keyValueLength);
889 }
890
891
892 int pos = boffset;
893 pos = Bytes.putInt(buffer, pos, keyLength);
894 pos = Bytes.putInt(buffer, pos, vlength);
895 pos = Bytes.putShort(buffer, pos, (short)(rlength & 0x0000ffff));
896 pos = Bytes.putBytes(buffer, pos, row, roffset, rlength);
897 pos = Bytes.putByte(buffer, pos, (byte) (flength & 0x0000ff));
898 if (flength != 0) {
899 pos = Bytes.putBytes(buffer, pos, family, foffset, flength);
900 }
901 if (qlength != 0) {
902 pos = Bytes.putBytes(buffer, pos, qualifier, qoffset, qlength);
903 }
904 pos = Bytes.putLong(buffer, pos, timestamp);
905 pos = Bytes.putByte(buffer, pos, type.getCode());
906 if (value != null && value.length > 0) {
907 pos = Bytes.putBytes(buffer, pos, value, voffset, vlength);
908 }
909
910 if (tagsLength > 0) {
911 pos = Bytes.putShort(buffer, pos, (short) tagsLength);
912 for (Tag t : tags) {
913 pos = Bytes.putBytes(buffer, pos, t.getBuffer(), t.getOffset(), t.getLength());
914 }
915 }
916 return keyValueLength;
917 }
918
919 private static void checkForTagsLength(int tagsLength) {
920 if (tagsLength > Short.MAX_VALUE) {
921 throw new IllegalArgumentException("tagslength "+ tagsLength + " > " + Short.MAX_VALUE);
922 }
923 }
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943 private static byte [] createByteArray(final byte [] row, final int roffset,
944 final int rlength, final byte [] family, final int foffset, int flength,
945 final byte [] qualifier, final int qoffset, int qlength,
946 final long timestamp, final Type type,
947 final byte [] value, final int voffset,
948 int vlength, byte[] tags, int tagsOffset, int tagsLength) {
949
950 checkParameters(row, rlength, family, flength, qlength, vlength);
951 checkForTagsLength(tagsLength);
952
953 int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
954 byte [] bytes =
955 new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength, tagsLength)];
956
957 int pos = 0;
958 pos = Bytes.putInt(bytes, pos, keyLength);
959 pos = Bytes.putInt(bytes, pos, vlength);
960 pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
961 pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
962 pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
963 if(flength != 0) {
964 pos = Bytes.putBytes(bytes, pos, family, foffset, flength);
965 }
966 if(qlength != 0) {
967 pos = Bytes.putBytes(bytes, pos, qualifier, qoffset, qlength);
968 }
969 pos = Bytes.putLong(bytes, pos, timestamp);
970 pos = Bytes.putByte(bytes, pos, type.getCode());
971 if (value != null && value.length > 0) {
972 pos = Bytes.putBytes(bytes, pos, value, voffset, vlength);
973 }
974
975 if (tagsLength > 0) {
976 pos = Bytes.putShort(bytes, pos, (short) (tagsLength));
977 pos = Bytes.putBytes(bytes, pos, tags, tagsOffset, tagsLength);
978 }
979 return bytes;
980 }
981
982
983
984
985
986 private static byte [] createByteArray(final byte [] row, final int roffset,
987 final int rlength, final byte [] family, final int foffset, int flength,
988 final Object qualifier, final int qoffset, int qlength,
989 final long timestamp, final Type type,
990 final Object value, final int voffset, int vlength, List<Tag> tags) {
991
992 checkParameters(row, rlength, family, flength, qlength, vlength);
993
994
995 int tagsLength = 0;
996 if (tags != null && !tags.isEmpty()) {
997 for (Tag t : tags) {
998 tagsLength += t.getLength();
999 }
1000 }
1001 checkForTagsLength(tagsLength);
1002
1003 int keyLength = (int) getKeyDataStructureSize(rlength, flength, qlength);
1004 byte[] bytes = new byte[(int) getKeyValueDataStructureSize(rlength, flength, qlength, vlength,
1005 tagsLength)];
1006
1007
1008 int pos = 0;
1009 pos = Bytes.putInt(bytes, pos, keyLength);
1010
1011 pos = Bytes.putInt(bytes, pos, vlength);
1012 pos = Bytes.putShort(bytes, pos, (short)(rlength & 0x0000ffff));
1013 pos = Bytes.putBytes(bytes, pos, row, roffset, rlength);
1014 pos = Bytes.putByte(bytes, pos, (byte)(flength & 0x0000ff));
1015 if(flength != 0) {
1016 pos = Bytes.putBytes(bytes, pos, family, foffset, flength);
1017 }
1018 if (qlength > 0) {
1019 if (qualifier instanceof ByteBuffer) {
1020 pos = Bytes.putByteBuffer(bytes, pos, (ByteBuffer) qualifier);
1021 } else {
1022 pos = Bytes.putBytes(bytes, pos, (byte[]) qualifier, qoffset, qlength);
1023 }
1024 }
1025 pos = Bytes.putLong(bytes, pos, timestamp);
1026 pos = Bytes.putByte(bytes, pos, type.getCode());
1027 if (vlength > 0) {
1028 if (value instanceof ByteBuffer) {
1029 pos = Bytes.putByteBuffer(bytes, pos, (ByteBuffer) value);
1030 } else {
1031 pos = Bytes.putBytes(bytes, pos, (byte[]) value, voffset, vlength);
1032 }
1033 }
1034
1035 if (tagsLength > 0) {
1036 pos = Bytes.putShort(bytes, pos, (short) (tagsLength));
1037 for (Tag t : tags) {
1038 pos = Bytes.putBytes(bytes, pos, t.getBuffer(), t.getOffset(), t.getLength());
1039 }
1040 }
1041 return bytes;
1042 }
1043
1044
1045
1046
1047 @Override
1048 public boolean equals(Object other) {
1049 if (!(other instanceof Cell)) {
1050 return false;
1051 }
1052 return CellComparator.equals(this, (Cell)other);
1053 }
1054
1055 @Override
1056 public int hashCode() {
1057 byte[] b = getBuffer();
1058 int start = getOffset(), end = getOffset() + getLength();
1059 int h = b[start++];
1060 for (int i = start; i < end; i++) {
1061 h = (h * 13) ^ b[i];
1062 }
1063 return h;
1064 }
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 @Override
1078 public KeyValue clone() throws CloneNotSupportedException {
1079 super.clone();
1080 byte [] b = new byte[this.length];
1081 System.arraycopy(this.bytes, this.offset, b, 0, this.length);
1082 KeyValue ret = new KeyValue(b, 0, b.length);
1083
1084
1085
1086 ret.setMvccVersion(mvcc);
1087 return ret;
1088 }
1089
1090
1091
1092
1093
1094
1095 public KeyValue shallowCopy() {
1096 KeyValue shallowCopy = new KeyValue(this.bytes, this.offset, this.length);
1097 shallowCopy.setMvccVersion(this.mvcc);
1098 return shallowCopy;
1099 }
1100
1101
1102
1103
1104
1105
1106
1107 public String toString() {
1108 if (this.bytes == null || this.bytes.length == 0) {
1109 return "empty";
1110 }
1111 return keyToString(this.bytes, this.offset + ROW_OFFSET, getKeyLength()) +
1112 "/vlen=" + getValueLength() + "/mvcc=" + mvcc;
1113 }
1114
1115
1116
1117
1118
1119 public static String keyToString(final byte [] k) {
1120 if (k == null) {
1121 return "";
1122 }
1123 return keyToString(k, 0, k.length);
1124 }
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134 public Map<String, Object> toStringMap() {
1135 Map<String, Object> stringMap = new HashMap<String, Object>();
1136 stringMap.put("row", Bytes.toStringBinary(getRow()));
1137 stringMap.put("family", Bytes.toStringBinary(getFamily()));
1138 stringMap.put("qualifier", Bytes.toStringBinary(getQualifier()));
1139 stringMap.put("timestamp", getTimestamp());
1140 stringMap.put("vlen", getValueLength());
1141 List<Tag> tags = getTags();
1142 if (tags != null) {
1143 List<String> tagsString = new ArrayList<String>();
1144 for (Tag t : tags) {
1145 tagsString.add((t.getType()) + ":" +Bytes.toStringBinary(t.getValue()));
1146 }
1147 stringMap.put("tag", tagsString);
1148 }
1149 return stringMap;
1150 }
1151
1152
1153
1154
1155
1156
1157
1158
1159 public static String keyToString(final byte [] b, final int o, final int l) {
1160 if (b == null) return "";
1161 int rowlength = Bytes.toShort(b, o);
1162 String row = Bytes.toStringBinary(b, o + Bytes.SIZEOF_SHORT, rowlength);
1163 int columnoffset = o + Bytes.SIZEOF_SHORT + 1 + rowlength;
1164 int familylength = b[columnoffset - 1];
1165 int columnlength = l - ((columnoffset - o) + TIMESTAMP_TYPE_SIZE);
1166 String family = familylength == 0? "":
1167 Bytes.toStringBinary(b, columnoffset, familylength);
1168 String qualifier = columnlength == 0? "":
1169 Bytes.toStringBinary(b, columnoffset + familylength,
1170 columnlength - familylength);
1171 long timestamp = Bytes.toLong(b, o + (l - TIMESTAMP_TYPE_SIZE));
1172 String timestampStr = humanReadableTimestamp(timestamp);
1173 byte type = b[o + l - 1];
1174 return row + "/" + family +
1175 (family != null && family.length() > 0? ":" :"") +
1176 qualifier + "/" + timestampStr + "/" + Type.codeToType(type);
1177 }
1178
1179 public static String humanReadableTimestamp(final long timestamp) {
1180 if (timestamp == HConstants.LATEST_TIMESTAMP) {
1181 return "LATEST_TIMESTAMP";
1182 }
1183 if (timestamp == HConstants.OLDEST_TIMESTAMP) {
1184 return "OLDEST_TIMESTAMP";
1185 }
1186 return String.valueOf(timestamp);
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199 @Deprecated
1200 public byte [] getBuffer() {
1201 return this.bytes;
1202 }
1203
1204
1205
1206
1207 public int getOffset() {
1208 return this.offset;
1209 }
1210
1211
1212
1213
1214 public int getLength() {
1215 return length;
1216 }
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231 private static int getLength(byte [] bytes, int offset) {
1232 int klength = ROW_OFFSET + Bytes.toInt(bytes, offset);
1233 int vlength = Bytes.toInt(bytes, offset + Bytes.SIZEOF_INT);
1234 return klength + vlength;
1235 }
1236
1237
1238
1239
1240 public int getKeyOffset() {
1241 return this.offset + ROW_OFFSET;
1242 }
1243
1244 public String getKeyString() {
1245 return Bytes.toStringBinary(getBuffer(), getKeyOffset(), getKeyLength());
1246 }
1247
1248
1249
1250
1251 public int getKeyLength() {
1252 return Bytes.toInt(this.bytes, this.offset);
1253 }
1254
1255
1256
1257
1258 @Override
1259 public byte[] getValueArray() {
1260 return bytes;
1261 }
1262
1263
1264
1265
1266 @Override
1267 public int getValueOffset() {
1268 int voffset = getKeyOffset() + getKeyLength();
1269 return voffset;
1270 }
1271
1272
1273
1274
1275 @Override
1276 public int getValueLength() {
1277 int vlength = Bytes.toInt(this.bytes, this.offset + Bytes.SIZEOF_INT);
1278 return vlength;
1279 }
1280
1281
1282
1283
1284 @Override
1285 public byte[] getRowArray() {
1286 return bytes;
1287 }
1288
1289
1290
1291
1292 @Override
1293 public int getRowOffset() {
1294 return getKeyOffset() + Bytes.SIZEOF_SHORT;
1295 }
1296
1297
1298
1299
1300 @Override
1301 public short getRowLength() {
1302 return Bytes.toShort(this.bytes, getKeyOffset());
1303 }
1304
1305
1306
1307
1308 @Override
1309 public byte[] getFamilyArray() {
1310 return bytes;
1311 }
1312
1313
1314
1315
1316 @Override
1317 public int getFamilyOffset() {
1318 return getFamilyOffset(getRowLength());
1319 }
1320
1321
1322
1323
1324 private int getFamilyOffset(int rlength) {
1325 return this.offset + ROW_OFFSET + Bytes.SIZEOF_SHORT + rlength + Bytes.SIZEOF_BYTE;
1326 }
1327
1328
1329
1330
1331 @Override
1332 public byte getFamilyLength() {
1333 return getFamilyLength(getFamilyOffset());
1334 }
1335
1336
1337
1338
1339 public byte getFamilyLength(int foffset) {
1340 return this.bytes[foffset-1];
1341 }
1342
1343
1344
1345
1346 @Override
1347 public byte[] getQualifierArray() {
1348 return bytes;
1349 }
1350
1351
1352
1353
1354 @Override
1355 public int getQualifierOffset() {
1356 return getQualifierOffset(getFamilyOffset());
1357 }
1358
1359
1360
1361
1362 private int getQualifierOffset(int foffset) {
1363 return foffset + getFamilyLength(foffset);
1364 }
1365
1366
1367
1368
1369 @Override
1370 public int getQualifierLength() {
1371 return getQualifierLength(getRowLength(),getFamilyLength());
1372 }
1373
1374
1375
1376
1377 private int getQualifierLength(int rlength, int flength) {
1378 return getKeyLength() - (int) getKeyDataStructureSize(rlength, flength, 0);
1379 }
1380
1381
1382
1383
1384 private int getTotalColumnLength(int rlength, int foffset) {
1385 int flength = getFamilyLength(foffset);
1386 int qlength = getQualifierLength(rlength,flength);
1387 return flength + qlength;
1388 }
1389
1390
1391
1392
1393 public int getTimestampOffset() {
1394 return getTimestampOffset(getKeyLength());
1395 }
1396
1397
1398
1399
1400
1401 private int getTimestampOffset(final int keylength) {
1402 return getKeyOffset() + keylength - TIMESTAMP_TYPE_SIZE;
1403 }
1404
1405
1406
1407
1408 public boolean isLatestTimestamp() {
1409 return Bytes.equals(getBuffer(), getTimestampOffset(), Bytes.SIZEOF_LONG,
1410 HConstants.LATEST_TIMESTAMP_BYTES, 0, Bytes.SIZEOF_LONG);
1411 }
1412
1413
1414
1415
1416
1417
1418 public boolean updateLatestStamp(final byte [] now) {
1419 if (this.isLatestTimestamp()) {
1420 int tsOffset = getTimestampOffset();
1421 System.arraycopy(now, 0, this.bytes, tsOffset, Bytes.SIZEOF_LONG);
1422
1423 return true;
1424 }
1425 return false;
1426 }
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441 public byte [] getKey() {
1442 int keylength = getKeyLength();
1443 byte [] key = new byte[keylength];
1444 System.arraycopy(getBuffer(), getKeyOffset(), key, 0, keylength);
1445 return key;
1446 }
1447
1448
1449
1450
1451
1452
1453
1454
1455 @Deprecated
1456 public byte [] getValue() {
1457 return CellUtil.cloneValue(this);
1458 }
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468 @Deprecated
1469 public byte [] getRow() {
1470 return CellUtil.cloneRow(this);
1471 }
1472
1473
1474
1475
1476
1477 @Override
1478 public long getTimestamp() {
1479 return getTimestamp(getKeyLength());
1480 }
1481
1482
1483
1484
1485
1486 long getTimestamp(final int keylength) {
1487 int tsOffset = getTimestampOffset(keylength);
1488 return Bytes.toLong(this.bytes, tsOffset);
1489 }
1490
1491
1492
1493
1494 @Deprecated
1495 public byte getType() {
1496 return getTypeByte();
1497 }
1498
1499
1500
1501
1502 @Override
1503 public byte getTypeByte() {
1504 return this.bytes[this.offset + getKeyLength() - 1 + ROW_OFFSET];
1505 }
1506
1507
1508
1509
1510
1511
1512 @Deprecated
1513 public boolean isDelete() {
1514 return KeyValue.isDelete(getType());
1515 }
1516
1517
1518
1519
1520 public boolean isDeleteType() {
1521
1522 return getTypeByte() == Type.Delete.getCode();
1523 }
1524
1525
1526
1527
1528 public boolean isDeleteFamily() {
1529 return getTypeByte() == Type.DeleteFamily.getCode();
1530 }
1531
1532
1533
1534
1535 public boolean isDeleteFamilyVersion() {
1536 return getTypeByte() == Type.DeleteFamilyVersion.getCode();
1537 }
1538
1539
1540
1541
1542
1543 public boolean isDeleteColumnOrFamily() {
1544 int t = getTypeByte();
1545 return t == Type.DeleteColumn.getCode() || t == Type.DeleteFamily.getCode();
1546 }
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556 @Deprecated
1557 public byte [] getFamily() {
1558 return CellUtil.cloneFamily(this);
1559 }
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570 @Deprecated
1571 public byte [] getQualifier() {
1572 return CellUtil.cloneQualifier(this);
1573 }
1574
1575
1576
1577
1578 @Override
1579 public int getTagsOffset() {
1580 short tagsLen = getTagsLength();
1581 if (tagsLen == 0) {
1582 return this.offset + this.length;
1583 }
1584 return this.offset + this.length - tagsLen;
1585 }
1586
1587
1588
1589
1590 @Override
1591 public short getTagsLength() {
1592 int tagsLen = this.length - (getKeyLength() + getValueLength() + KEYVALUE_INFRASTRUCTURE_SIZE);
1593 if (tagsLen > 0) {
1594
1595
1596 tagsLen -= TAGS_LENGTH_SIZE;
1597 }
1598 return (short) tagsLen;
1599 }
1600
1601
1602
1603
1604
1605 public List<Tag> getTags() {
1606 short tagsLength = getTagsLength();
1607 if (tagsLength == 0) {
1608 return EMPTY_ARRAY_LIST;
1609 }
1610 return Tag.asList(getBuffer(), getTagsOffset(), tagsLength);
1611 }
1612
1613
1614
1615
1616 @Override
1617 public byte[] getTagsArray() {
1618 return bytes;
1619 }
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631 public boolean matchingFamily(final byte [] family) {
1632 if (this.length == 0 || this.bytes.length == 0) {
1633 return false;
1634 }
1635 return Bytes.equals(family, 0, family.length,
1636 this.bytes, getFamilyOffset(), getFamilyLength());
1637 }
1638
1639
1640
1641
1642
1643 public boolean matchingQualifier(final byte [] qualifier) {
1644 return matchingQualifier(qualifier, 0, qualifier.length);
1645 }
1646
1647 public boolean matchingQualifier(final byte [] qualifier, int offset, int length) {
1648 return Bytes.equals(qualifier, offset, length,
1649 this.bytes, getQualifierOffset(), getQualifierLength());
1650 }
1651
1652 public boolean matchingQualifier(final KeyValue other) {
1653 return matchingQualifier(other.getBuffer(), other.getQualifierOffset(),
1654 other.getQualifierLength());
1655 }
1656
1657 public boolean matchingRow(final byte [] row) {
1658 return matchingRow(row, 0, row.length);
1659 }
1660
1661 public boolean matchingRow(final byte[] row, int offset, int length) {
1662 return Bytes.equals(row, offset, length,
1663 this.bytes, getRowOffset(), getRowLength());
1664 }
1665
1666 public boolean matchingRow(KeyValue other) {
1667 return matchingRow(other.getBuffer(), other.getRowOffset(),
1668 other.getRowLength());
1669 }
1670
1671
1672
1673
1674
1675
1676
1677 public boolean matchingColumn(final byte[] family, final byte[] qualifier) {
1678 return matchingColumn(family, 0, len(family), qualifier, 0, len(qualifier));
1679 }
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693 public boolean matchingColumn(final byte [] family, final int foffset, final int flength,
1694 final byte [] qualifier, final int qoffset, final int qlength) {
1695 int rl = getRowLength();
1696 int o = getFamilyOffset(rl);
1697 int fl = getFamilyLength(o);
1698 if (!Bytes.equals(family, foffset, flength, this.bytes, o, fl)) {
1699 return false;
1700 }
1701
1702 int ql = getQualifierLength(rl, fl);
1703 if (qualifier == null || qlength == 0) {
1704 return (ql == 0);
1705 }
1706 return Bytes.equals(qualifier, qoffset, qlength, this.bytes, o + fl, ql);
1707 }
1708
1709
1710
1711
1712
1713
1714
1715
1716 public KeyValue createKeyOnly(boolean lenAsVal) {
1717
1718
1719 int dataLen = lenAsVal? Bytes.SIZEOF_INT : 0;
1720 byte [] newBuffer = new byte[getKeyLength() + ROW_OFFSET + dataLen];
1721 System.arraycopy(this.bytes, this.offset, newBuffer, 0,
1722 Math.min(newBuffer.length,this.length));
1723 Bytes.putInt(newBuffer, Bytes.SIZEOF_INT, dataLen);
1724 if (lenAsVal) {
1725 Bytes.putInt(newBuffer, newBuffer.length - dataLen, this.getValueLength());
1726 }
1727 return new KeyValue(newBuffer);
1728 }
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743 public static byte [][] parseColumn(byte [] c) {
1744 final int index = getDelimiter(c, 0, c.length, COLUMN_FAMILY_DELIMITER);
1745 if (index == -1) {
1746
1747 return new byte [][] { c };
1748 } else if(index == c.length - 1) {
1749
1750 byte [] family = new byte[c.length-1];
1751 System.arraycopy(c, 0, family, 0, family.length);
1752 return new byte [][] { family, HConstants.EMPTY_BYTE_ARRAY};
1753 }
1754
1755 final byte [][] result = new byte [2][];
1756 result[0] = new byte [index];
1757 System.arraycopy(c, 0, result[0], 0, index);
1758 final int len = c.length - (index + 1);
1759 result[1] = new byte[len];
1760 System.arraycopy(c, index + 1
1761 return result;
1762 }
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772 public static byte [] makeColumn(byte [] family, byte [] qualifier) {
1773 return Bytes.add(family, COLUMN_FAMILY_DELIM_ARRAY, qualifier);
1774 }
1775
1776
1777
1778
1779
1780 static int getRequiredDelimiterInReverse(final byte [] b,
1781 final int offset, final int length, final int delimiter) {
1782 int index = getDelimiterInReverse(b, offset, length, delimiter);
1783 if (index < 0) {
1784 throw new IllegalArgumentException("hbase:meta key must have two '" + (char)delimiter + "' "
1785 + "delimiters and have the following format: '<table>,<key>,<etc>'");
1786 }
1787 return index;
1788 }
1789
1790
1791
1792
1793
1794
1795
1796 public static int getDelimiter(final byte [] b, int offset, final int length,
1797 final int delimiter) {
1798 if (b == null) {
1799 throw new IllegalArgumentException("Passed buffer is null");
1800 }
1801 int result = -1;
1802 for (int i = offset; i < length + offset; i++) {
1803 if (b[i] == delimiter) {
1804 result = i;
1805 break;
1806 }
1807 }
1808 return result;
1809 }
1810
1811
1812
1813
1814
1815
1816
1817 public static int getDelimiterInReverse(final byte [] b, final int offset,
1818 final int length, final int delimiter) {
1819 if (b == null) {
1820 throw new IllegalArgumentException("Passed buffer is null");
1821 }
1822 int result = -1;
1823 for (int i = (offset + length) - 1; i >= offset; i--) {
1824 if (b[i] == delimiter) {
1825 result = i;
1826 break;
1827 }
1828 }
1829 return result;
1830 }
1831
1832
1833
1834
1835
1836 public static class MetaComparator extends KVComparator {
1837
1838
1839
1840
1841 @Override
1842 public int compareRows(byte [] left, int loffset, int llength,
1843 byte [] right, int roffset, int rlength) {
1844 int leftDelimiter = getDelimiter(left, loffset, llength,
1845 HConstants.DELIMITER);
1846 int rightDelimiter = getDelimiter(right, roffset, rlength,
1847 HConstants.DELIMITER);
1848 if (leftDelimiter < 0 && rightDelimiter >= 0) {
1849
1850 return -1;
1851 } else if (rightDelimiter < 0 && leftDelimiter >= 0) {
1852 return 1;
1853 } else if (leftDelimiter < 0 && rightDelimiter < 0) {
1854 return 0;
1855 }
1856
1857 int result = Bytes.compareTo(left, loffset, leftDelimiter - loffset,
1858 right, roffset, rightDelimiter - roffset);
1859 if (result != 0) {
1860 return result;
1861 }
1862
1863
1864 leftDelimiter++;
1865 rightDelimiter++;
1866 int leftFarDelimiter = getRequiredDelimiterInReverse(left, leftDelimiter,
1867 llength - (leftDelimiter - loffset), HConstants.DELIMITER);
1868 int rightFarDelimiter = getRequiredDelimiterInReverse(right,
1869 rightDelimiter, rlength - (rightDelimiter - roffset),
1870 HConstants.DELIMITER);
1871
1872 result = super.compareRows(left, leftDelimiter,
1873 leftFarDelimiter - leftDelimiter, right, rightDelimiter,
1874 rightFarDelimiter - rightDelimiter);
1875 if (result != 0) {
1876 return result;
1877 }
1878
1879 leftFarDelimiter++;
1880 rightFarDelimiter++;
1881 result = Bytes.compareTo(left, leftFarDelimiter, llength - (leftFarDelimiter - loffset),
1882 right, rightFarDelimiter, rlength - (rightFarDelimiter - roffset));
1883 return result;
1884 }
1885
1886
1887
1888
1889 @Override
1890 public byte[] getShortMidpointKey(final byte[] leftKey, final byte[] rightKey) {
1891 return Arrays.copyOf(rightKey, rightKey.length);
1892 }
1893
1894
1895
1896
1897
1898
1899
1900 @Override
1901 public String getLegacyKeyComparatorName() {
1902 return "org.apache.hadoop.hbase.KeyValue$MetaKeyComparator";
1903 }
1904
1905 @Override
1906 protected Object clone() throws CloneNotSupportedException {
1907 return new MetaComparator();
1908 }
1909
1910
1911
1912
1913 @Override
1914 protected int compareRowKey(final Cell l, final Cell r) {
1915 byte[] left = l.getRowArray();
1916 int loffset = l.getRowOffset();
1917 int llength = l.getRowLength();
1918 byte[] right = r.getRowArray();
1919 int roffset = r.getRowOffset();
1920 int rlength = r.getRowLength();
1921 return compareRows(left, loffset, llength, right, roffset, rlength);
1922 }
1923 }
1924
1925
1926
1927
1928
1929
1930 public static class KVComparator implements RawComparator<Cell>, SamePrefixComparator<byte[]> {
1931
1932
1933
1934
1935
1936
1937
1938 public String getLegacyKeyComparatorName() {
1939 return "org.apache.hadoop.hbase.KeyValue$KeyComparator";
1940 }
1941
1942 @Override
1943 public int compare(byte[] l, int loff, int llen, byte[] r, int roff, int rlen) {
1944 return compareFlatKey(l,loff,llen, r,roff,rlen);
1945 }
1946
1947
1948
1949
1950
1951
1952
1953
1954 protected int compareRowKey(final Cell left, final Cell right) {
1955 return Bytes.compareTo(
1956 left.getRowArray(), left.getRowOffset(), left.getRowLength(),
1957 right.getRowArray(), right.getRowOffset(), right.getRowLength());
1958 }
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971 public int compareFlatKey(byte[] left, int loffset, int llength,
1972 byte[] right, int roffset, int rlength) {
1973
1974 short lrowlength = Bytes.toShort(left, loffset);
1975 short rrowlength = Bytes.toShort(right, roffset);
1976 int compare = compareRows(left, loffset + Bytes.SIZEOF_SHORT,
1977 lrowlength, right, roffset + Bytes.SIZEOF_SHORT, rrowlength);
1978 if (compare != 0) {
1979 return compare;
1980 }
1981
1982
1983
1984
1985 return compareWithoutRow(0, left, loffset, llength, right, roffset,
1986 rlength, rrowlength);
1987 }
1988
1989 public int compareFlatKey(byte[] left, byte[] right) {
1990 return compareFlatKey(left, 0, left.length, right, 0, right.length);
1991 }
1992
1993
1994
1995
1996
1997 public int compare(final Cell left, final Cell right) {
1998
1999 int compare = compareRowKey(left, right);
2000 if (compare != 0) {
2001 return compare;
2002 }
2003
2004
2005 byte ltype = left.getTypeByte();
2006 byte rtype = right.getTypeByte();
2007
2008
2009
2010
2011
2012 int lcfqLen = left.getFamilyLength() + left.getQualifierLength() ;
2013 int rcfqLen = right.getFamilyLength() + right.getQualifierLength() ;
2014 if (lcfqLen == 0 && ltype == Type.Minimum.getCode()) {
2015
2016 return 1;
2017 }
2018 if (rcfqLen == 0 && rtype == Type.Minimum.getCode()) {
2019 return -1;
2020 }
2021
2022
2023
2024
2025
2026 compare = Bytes.compareTo(
2027 left.getFamilyArray(), left.getFamilyOffset(), left.getFamilyLength(),
2028 right.getFamilyArray(), right.getFamilyOffset(), right.getFamilyLength());
2029 if (compare != 0) {
2030 return compare;
2031 }
2032
2033
2034 compare = Bytes.compareTo(
2035 left.getQualifierArray(), left.getQualifierOffset(), left.getQualifierLength(),
2036 right.getQualifierArray(), right.getQualifierOffset(), right.getQualifierLength());
2037 if (compare!= 0) {
2038 return compare;
2039 }
2040
2041
2042 long ltimestamp = left.getTimestamp();
2043 long rtimestamp = right.getTimestamp();
2044 compare = compareTimestamps(ltimestamp, rtimestamp);
2045 if (compare != 0) {
2046 return compare;
2047 }
2048
2049
2050
2051
2052
2053 compare = (0xff & rtype) - (0xff & ltype);
2054 if (compare != 0) {
2055 return compare;
2056 }
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066 long leftChangeSeqNum = getReplaySeqNum(left);
2067 long RightChangeSeqNum = getReplaySeqNum(right);
2068 if (leftChangeSeqNum != Long.MAX_VALUE || RightChangeSeqNum != Long.MAX_VALUE) {
2069 return Longs.compare(RightChangeSeqNum, leftChangeSeqNum);
2070 }
2071
2072
2073 return Longs.compare(right.getMvccVersion(), left.getMvccVersion());
2074 }
2075
2076
2077
2078
2079
2080
2081 private long getReplaySeqNum(final Cell c) {
2082 Tag tag = Tag.getTag(c.getTagsArray(), c.getTagsOffset(), c.getTagsLength(),
2083 TagType.LOG_REPLAY_TAG_TYPE);
2084
2085 if(tag != null) {
2086 return Bytes.toLong(tag.getBuffer(), tag.getTagOffset(), tag.getTagLength());
2087 }
2088 return Long.MAX_VALUE;
2089 }
2090
2091 public int compareTimestamps(final KeyValue left, final KeyValue right) {
2092
2093 long ltimestamp = left.getTimestamp(left.getKeyLength());
2094 long rtimestamp = right.getTimestamp(right.getKeyLength());
2095 return compareTimestamps(ltimestamp, rtimestamp);
2096 }
2097
2098
2099
2100
2101
2102
2103 public int compareRows(final KeyValue left, final KeyValue right) {
2104 return compareRows(left.getBuffer(),left.getRowOffset(), left.getRowLength(),
2105 right.getBuffer(), right.getRowOffset(), right.getRowLength());
2106 }
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118 public int compareRows(byte [] left, int loffset, int llength,
2119 byte [] right, int roffset, int rlength) {
2120 return Bytes.compareTo(left, loffset, llength, right, roffset, rlength);
2121 }
2122
2123 int compareColumns(final KeyValue left, final short lrowlength,
2124 final KeyValue right, final short rrowlength) {
2125 int lfoffset = left.getFamilyOffset(lrowlength);
2126 int rfoffset = right.getFamilyOffset(rrowlength);
2127 int lclength = left.getTotalColumnLength(lrowlength,lfoffset);
2128 int rclength = right.getTotalColumnLength(rrowlength, rfoffset);
2129 int lfamilylength = left.getFamilyLength(lfoffset);
2130 int rfamilylength = right.getFamilyLength(rfoffset);
2131 return compareColumns(left.getBuffer(), lfoffset,
2132 lclength, lfamilylength,
2133 right.getBuffer(), rfoffset, rclength, rfamilylength);
2134 }
2135
2136 protected int compareColumns(
2137 byte [] left, int loffset, int llength, final int lfamilylength,
2138 byte [] right, int roffset, int rlength, final int rfamilylength) {
2139
2140 int diff = Bytes.compareTo(left, loffset, lfamilylength,
2141 right, roffset, rfamilylength);
2142 if (diff != 0) {
2143 return diff;
2144 }
2145
2146 return Bytes.compareTo(left, loffset + lfamilylength,
2147 llength - lfamilylength,
2148 right, roffset + rfamilylength, rlength - rfamilylength);
2149 }
2150
2151 static int compareTimestamps(final long ltimestamp, final long rtimestamp) {
2152
2153
2154
2155
2156 if (ltimestamp < rtimestamp) {
2157 return 1;
2158 } else if (ltimestamp > rtimestamp) {
2159 return -1;
2160 }
2161 return 0;
2162 }
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175 @Override
2176 public int compareIgnoringPrefix(int commonPrefix, byte[] left,
2177 int loffset, int llength, byte[] right, int roffset, int rlength) {
2178
2179 short lrowlength = Bytes.toShort(left, loffset);
2180 short rrowlength;
2181
2182 int comparisonResult = 0;
2183 if (commonPrefix < ROW_LENGTH_SIZE) {
2184
2185 rrowlength = Bytes.toShort(right, roffset);
2186 comparisonResult = compareRows(left, loffset + ROW_LENGTH_SIZE,
2187 lrowlength, right, roffset + ROW_LENGTH_SIZE, rrowlength);
2188 } else {
2189 rrowlength = lrowlength;
2190 if (commonPrefix < ROW_LENGTH_SIZE + rrowlength) {
2191
2192
2193 int common = commonPrefix - ROW_LENGTH_SIZE;
2194 comparisonResult = compareRows(
2195 left, loffset + common + ROW_LENGTH_SIZE, lrowlength - common,
2196 right, roffset + common + ROW_LENGTH_SIZE, rrowlength - common);
2197 }
2198 }
2199 if (comparisonResult != 0) {
2200 return comparisonResult;
2201 }
2202
2203 assert lrowlength == rrowlength;
2204 return compareWithoutRow(commonPrefix, left, loffset, llength, right,
2205 roffset, rlength, lrowlength);
2206 }
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218 private int compareWithoutRow(int commonPrefix, byte[] left, int loffset,
2219 int llength, byte[] right, int roffset, int rlength, short rowlength) {
2220
2221
2222
2223
2224
2225 int commonLength = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + rowlength;
2226
2227
2228 int commonLengthWithTSAndType = TIMESTAMP_TYPE_SIZE + commonLength;
2229
2230 int lcolumnlength = llength - commonLengthWithTSAndType;
2231 int rcolumnlength = rlength - commonLengthWithTSAndType;
2232
2233 byte ltype = left[loffset + (llength - 1)];
2234 byte rtype = right[roffset + (rlength - 1)];
2235
2236
2237
2238
2239
2240
2241 if (lcolumnlength == 0 && ltype == Type.Minimum.getCode()) {
2242
2243 return 1;
2244 }
2245 if (rcolumnlength == 0 && rtype == Type.Minimum.getCode()) {
2246 return -1;
2247 }
2248
2249 int lfamilyoffset = commonLength + loffset;
2250 int rfamilyoffset = commonLength + roffset;
2251
2252
2253 int lfamilylength = left[lfamilyoffset - 1];
2254 int rfamilylength = right[rfamilyoffset - 1];
2255
2256
2257 boolean sameFamilySize = (lfamilylength == rfamilylength);
2258 int common = 0;
2259 if (commonPrefix > 0) {
2260 common = Math.max(0, commonPrefix - commonLength);
2261 if (!sameFamilySize) {
2262
2263
2264 common = Math.min(common, Math.min(lfamilylength, rfamilylength));
2265 } else {
2266 common = Math.min(common, Math.min(lcolumnlength, rcolumnlength));
2267 }
2268 }
2269 if (!sameFamilySize) {
2270
2271 return Bytes.compareTo(left, lfamilyoffset + common, lfamilylength
2272 - common, right, rfamilyoffset + common, rfamilylength - common);
2273 }
2274
2275 final int comparison = Bytes.compareTo(left, lfamilyoffset + common,
2276 lcolumnlength - common, right, rfamilyoffset + common,
2277 rcolumnlength - common);
2278 if (comparison != 0) {
2279 return comparison;
2280 }
2281
2282
2283
2284 long ltimestamp = Bytes.toLong(left,
2285 loffset + (llength - TIMESTAMP_TYPE_SIZE));
2286 long rtimestamp = Bytes.toLong(right,
2287 roffset + (rlength - TIMESTAMP_TYPE_SIZE));
2288 int compare = compareTimestamps(ltimestamp, rtimestamp);
2289 if (compare != 0) {
2290 return compare;
2291 }
2292
2293
2294
2295
2296
2297 return (0xff & rtype) - (0xff & ltype);
2298 }
2299
2300
2301
2302
2303
2304
2305
2306 public boolean matchingRowColumn(final KeyValue left,
2307 final KeyValue right) {
2308 short lrowlength = left.getRowLength();
2309 short rrowlength = right.getRowLength();
2310
2311
2312 if ((left.getTimestampOffset() - left.getOffset()) !=
2313 (right.getTimestampOffset() - right.getOffset())) {
2314 return false;
2315 }
2316
2317 if (!matchingRows(left, lrowlength, right, rrowlength)) {
2318 return false;
2319 }
2320
2321 int lfoffset = left.getFamilyOffset(lrowlength);
2322 int rfoffset = right.getFamilyOffset(rrowlength);
2323 int lclength = left.getTotalColumnLength(lrowlength,lfoffset);
2324 int rclength = right.getTotalColumnLength(rrowlength, rfoffset);
2325 int lfamilylength = left.getFamilyLength(lfoffset);
2326 int rfamilylength = right.getFamilyLength(rfoffset);
2327 int ccRes = compareColumns(left.getBuffer(), lfoffset, lclength, lfamilylength,
2328 right.getBuffer(), rfoffset, rclength, rfamilylength);
2329 return ccRes == 0;
2330 }
2331
2332
2333
2334
2335
2336
2337
2338 public boolean matchingRows(final KeyValue left, final KeyValue right) {
2339 short lrowlength = left.getRowLength();
2340 short rrowlength = right.getRowLength();
2341 return matchingRows(left, lrowlength, right, rrowlength);
2342 }
2343
2344
2345
2346
2347
2348
2349
2350
2351 private boolean matchingRows(final KeyValue left, final short lrowlength,
2352 final KeyValue right, final short rrowlength) {
2353 return lrowlength == rrowlength &&
2354 matchingRows(left.getBuffer(), left.getRowOffset(), lrowlength,
2355 right.getBuffer(), right.getRowOffset(), rrowlength);
2356 }
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368 public boolean matchingRows(final byte [] left, final int loffset, final int llength,
2369 final byte [] right, final int roffset, final int rlength) {
2370 return Bytes.equals(left, loffset, llength, right, roffset, rlength);
2371 }
2372
2373 public byte[] calcIndexKey(byte[] lastKeyOfPreviousBlock, byte[] firstKeyInBlock) {
2374 byte[] fakeKey = getShortMidpointKey(lastKeyOfPreviousBlock, firstKeyInBlock);
2375 if (compareFlatKey(fakeKey, firstKeyInBlock) > 0) {
2376 LOG.error("Unexpected getShortMidpointKey result, fakeKey:"
2377 + Bytes.toStringBinary(fakeKey) + ", firstKeyInBlock:"
2378 + Bytes.toStringBinary(firstKeyInBlock));
2379 return firstKeyInBlock;
2380 }
2381 if (lastKeyOfPreviousBlock != null && compareFlatKey(lastKeyOfPreviousBlock, fakeKey) >= 0) {
2382 LOG.error("Unexpected getShortMidpointKey result, lastKeyOfPreviousBlock:" +
2383 Bytes.toStringBinary(lastKeyOfPreviousBlock) + ", fakeKey:" +
2384 Bytes.toStringBinary(fakeKey));
2385 return firstKeyInBlock;
2386 }
2387 return fakeKey;
2388 }
2389
2390
2391
2392
2393
2394
2395
2396 public byte[] getShortMidpointKey(final byte[] leftKey, final byte[] rightKey) {
2397 if (rightKey == null) {
2398 throw new IllegalArgumentException("rightKey can not be null");
2399 }
2400 if (leftKey == null) {
2401 return Arrays.copyOf(rightKey, rightKey.length);
2402 }
2403 if (compareFlatKey(leftKey, rightKey) >= 0) {
2404 throw new IllegalArgumentException("Unexpected input, leftKey:" + Bytes.toString(leftKey)
2405 + ", rightKey:" + Bytes.toString(rightKey));
2406 }
2407
2408 short leftRowLength = Bytes.toShort(leftKey, 0);
2409 short rightRowLength = Bytes.toShort(rightKey, 0);
2410 int leftCommonLength = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + leftRowLength;
2411 int rightCommonLength = ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + rightRowLength;
2412 int leftCommonLengthWithTSAndType = TIMESTAMP_TYPE_SIZE + leftCommonLength;
2413 int rightCommonLengthWithTSAndType = TIMESTAMP_TYPE_SIZE + rightCommonLength;
2414 int leftColumnLength = leftKey.length - leftCommonLengthWithTSAndType;
2415 int rightColumnLength = rightKey.length - rightCommonLengthWithTSAndType;
2416
2417 if (leftRowLength == rightRowLength && compareRows(leftKey, ROW_LENGTH_SIZE, leftRowLength,
2418 rightKey, ROW_LENGTH_SIZE, rightRowLength) == 0) {
2419
2420 int comparison = Bytes.compareTo(leftKey, leftCommonLength, leftColumnLength, rightKey,
2421 rightCommonLength, rightColumnLength);
2422
2423 if (comparison == 0) {
2424 return Arrays.copyOf(rightKey, rightKey.length);
2425 }
2426
2427 byte[] newKey = Arrays.copyOf(rightKey, rightKey.length);
2428 Bytes.putLong(newKey, rightKey.length - TIMESTAMP_TYPE_SIZE, HConstants.LATEST_TIMESTAMP);
2429 Bytes.putByte(newKey, rightKey.length - TYPE_SIZE, Type.Maximum.getCode());
2430 return newKey;
2431 }
2432
2433 short minLength = leftRowLength < rightRowLength ? leftRowLength : rightRowLength;
2434 short diffIdx = 0;
2435 while (diffIdx < minLength
2436 && leftKey[ROW_LENGTH_SIZE + diffIdx] == rightKey[ROW_LENGTH_SIZE + diffIdx]) {
2437 diffIdx++;
2438 }
2439 byte[] newRowKey = null;
2440 if (diffIdx >= minLength) {
2441
2442 newRowKey = new byte[diffIdx + 1];
2443 System.arraycopy(rightKey, ROW_LENGTH_SIZE, newRowKey, 0, diffIdx + 1);
2444 } else {
2445 int diffByte = leftKey[ROW_LENGTH_SIZE + diffIdx];
2446 if ((0xff & diffByte) < 0xff && (diffByte + 1) <
2447 (rightKey[ROW_LENGTH_SIZE + diffIdx] & 0xff)) {
2448 newRowKey = new byte[diffIdx + 1];
2449 System.arraycopy(leftKey, ROW_LENGTH_SIZE, newRowKey, 0, diffIdx);
2450 newRowKey[diffIdx] = (byte) (diffByte + 1);
2451 } else {
2452 newRowKey = new byte[diffIdx + 1];
2453 System.arraycopy(rightKey, ROW_LENGTH_SIZE, newRowKey, 0, diffIdx + 1);
2454 }
2455 }
2456 return new KeyValue(newRowKey, null, null, HConstants.LATEST_TIMESTAMP,
2457 Type.Maximum).getKey();
2458 }
2459
2460 @Override
2461 protected Object clone() throws CloneNotSupportedException {
2462 return new KVComparator();
2463 }
2464
2465 }
2466
2467
2468
2469
2470
2471
2472
2473
2474 public static KeyValue createLastOnRow(final byte[] row) {
2475 return new KeyValue(row, null, null, HConstants.LATEST_TIMESTAMP, Type.Minimum);
2476 }
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486 public static KeyValue createFirstOnRow(final byte [] row) {
2487 return createFirstOnRow(row, HConstants.LATEST_TIMESTAMP);
2488 }
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498 public static KeyValue createFirstOnRow(final byte [] row, int roffset, short rlength) {
2499 return new KeyValue(row, roffset, rlength,
2500 null, 0, 0, null, 0, 0, HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0);
2501 }
2502
2503
2504
2505
2506
2507
2508
2509
2510 public static KeyValue createFirstOnRow(final byte [] row,
2511 final long ts) {
2512 return new KeyValue(row, null, null, ts, Type.Maximum);
2513 }
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524 public static KeyValue createFirstOnRow(final byte [] row, final byte [] family,
2525 final byte [] qualifier) {
2526 return new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP, Type.Maximum);
2527 }
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538 public static KeyValue createFirstDeleteFamilyOnRow(final byte [] row,
2539 final byte [] family) {
2540 return new KeyValue(row, family, null, HConstants.LATEST_TIMESTAMP,
2541 Type.DeleteFamily);
2542 }
2543
2544
2545
2546
2547
2548
2549
2550
2551 public static KeyValue createFirstOnRow(final byte [] row, final byte [] f,
2552 final byte [] q, final long ts) {
2553 return new KeyValue(row, f, q, ts, Type.Maximum);
2554 }
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572 public static KeyValue createFirstOnRow(final byte [] row,
2573 final int roffset, final int rlength, final byte [] family,
2574 final int foffset, final int flength, final byte [] qualifier,
2575 final int qoffset, final int qlength) {
2576 return new KeyValue(row, roffset, rlength, family,
2577 foffset, flength, qualifier, qoffset, qlength,
2578 HConstants.LATEST_TIMESTAMP, Type.Maximum, null, 0, 0);
2579 }
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597 public static KeyValue createFirstOnRow(byte [] buffer, final byte [] row,
2598 final byte [] family, final byte [] qualifier)
2599 throws IllegalArgumentException {
2600
2601 return createFirstOnRow(buffer, 0, row, 0, row.length,
2602 family, 0, family.length,
2603 qualifier, 0, qualifier.length);
2604 }
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629 public static KeyValue createFirstOnRow(byte [] buffer, final int boffset,
2630 final byte [] row, final int roffset, final int rlength,
2631 final byte [] family, final int foffset, final int flength,
2632 final byte [] qualifier, final int qoffset, final int qlength)
2633 throws IllegalArgumentException {
2634
2635 long lLength = getKeyValueDataStructureSize(rlength, flength, qlength, 0);
2636
2637 if (lLength > Integer.MAX_VALUE) {
2638 throw new IllegalArgumentException("KeyValue length " + lLength + " > " + Integer.MAX_VALUE);
2639 }
2640 int iLength = (int) lLength;
2641 if (buffer.length - boffset < iLength) {
2642 throw new IllegalArgumentException("Buffer size " + (buffer.length - boffset) + " < " +
2643 iLength);
2644 }
2645
2646 int len = writeByteArray(buffer, boffset, row, roffset, rlength, family, foffset, flength,
2647 qualifier, qoffset, qlength, HConstants.LATEST_TIMESTAMP, KeyValue.Type.Maximum,
2648 null, 0, 0, null);
2649 return new KeyValue(buffer, boffset, len);
2650 }
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668 public static KeyValue createLastOnRow(final byte [] row,
2669 final int roffset, final int rlength, final byte [] family,
2670 final int foffset, final int flength, final byte [] qualifier,
2671 final int qoffset, final int qlength) {
2672 return new KeyValue(row, roffset, rlength, family,
2673 foffset, flength, qualifier, qoffset, qlength,
2674 HConstants.OLDEST_TIMESTAMP, Type.Minimum, null, 0, 0);
2675 }
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685 public KeyValue createLastOnRowCol() {
2686 return new KeyValue(
2687 bytes, getRowOffset(), getRowLength(),
2688 bytes, getFamilyOffset(), getFamilyLength(),
2689 bytes, getQualifierOffset(), getQualifierLength(),
2690 HConstants.OLDEST_TIMESTAMP, Type.Minimum, null, 0, 0);
2691 }
2692
2693
2694
2695
2696
2697
2698
2699
2700 public KeyValue createFirstOnRowColTS(long ts) {
2701 return new KeyValue(
2702 bytes, getRowOffset(), getRowLength(),
2703 bytes, getFamilyOffset(), getFamilyLength(),
2704 bytes, getQualifierOffset(), getQualifierLength(),
2705 ts, Type.Maximum, bytes, getValueOffset(), getValueLength());
2706 }
2707
2708
2709
2710
2711
2712
2713 public static KeyValue createKeyValueFromKey(final byte [] b) {
2714 return createKeyValueFromKey(b, 0, b.length);
2715 }
2716
2717
2718
2719
2720
2721
2722 public static KeyValue createKeyValueFromKey(final ByteBuffer bb) {
2723 return createKeyValueFromKey(bb.array(), bb.arrayOffset(), bb.limit());
2724 }
2725
2726
2727
2728
2729
2730
2731
2732
2733 public static KeyValue createKeyValueFromKey(final byte [] b, final int o,
2734 final int l) {
2735 byte [] newb = new byte[l + ROW_OFFSET];
2736 System.arraycopy(b, o, newb, ROW_OFFSET, l);
2737 Bytes.putInt(newb, 0, l);
2738 Bytes.putInt(newb, Bytes.SIZEOF_INT, 0);
2739 return new KeyValue(newb);
2740 }
2741
2742
2743
2744
2745
2746
2747
2748
2749 public static KeyValue create(final DataInput in) throws IOException {
2750 return create(in.readInt(), in);
2751 }
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761 public static KeyValue create(int length, final DataInput in) throws IOException {
2762 if (length == 0) return null;
2763
2764 byte [] bytes = new byte[length];
2765 in.readFully(bytes);
2766 return new KeyValue(bytes, 0, length);
2767 }
2768
2769
2770
2771
2772
2773
2774
2775 public static KeyValue cloneAndAddTags(Cell c, List<Tag> newTags) {
2776 List<Tag> existingTags = null;
2777 if(c.getTagsLength() > 0) {
2778 existingTags = Tag.asList(c.getTagsArray(), c.getTagsOffset(), c.getTagsLength());
2779 existingTags.addAll(newTags);
2780 } else {
2781 existingTags = newTags;
2782 }
2783 return new KeyValue(c.getRowArray(), c.getRowOffset(), (int)c.getRowLength(),
2784 c.getFamilyArray(), c.getFamilyOffset(), (int)c.getFamilyLength(),
2785 c.getQualifierArray(), c.getQualifierOffset(), (int) c.getQualifierLength(),
2786 c.getTimestamp(), Type.codeToType(c.getTypeByte()), c.getValueArray(), c.getValueOffset(),
2787 c.getValueLength(), existingTags);
2788 }
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798 public static KeyValue iscreate(final InputStream in) throws IOException {
2799 byte [] intBytes = new byte[Bytes.SIZEOF_INT];
2800 int bytesRead = 0;
2801 while (bytesRead < intBytes.length) {
2802 int n = in.read(intBytes, bytesRead, intBytes.length - bytesRead);
2803 if (n < 0) {
2804 if (bytesRead == 0) return null;
2805 throw new IOException("Failed read of int, read " + bytesRead + " bytes");
2806 }
2807 bytesRead += n;
2808 }
2809
2810 byte [] bytes = new byte[Bytes.toInt(intBytes)];
2811 IOUtils.readFully(in, bytes, 0, bytes.length);
2812 return new KeyValue(bytes, 0, bytes.length);
2813 }
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823 public static long write(final KeyValue kv, final DataOutput out) throws IOException {
2824
2825
2826 int length = kv.getLength();
2827 out.writeInt(length);
2828 out.write(kv.getBuffer(), kv.getOffset(), length);
2829 return length + Bytes.SIZEOF_INT;
2830 }
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843 @Deprecated
2844 public static long oswrite(final KeyValue kv, final OutputStream out)
2845 throws IOException {
2846 int length = kv.getLength();
2847
2848 out.write(Bytes.toBytes(length));
2849 out.write(kv.getBuffer(), kv.getOffset(), length);
2850 return length + Bytes.SIZEOF_INT;
2851 }
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865 public static long oswrite(final KeyValue kv, final OutputStream out, final boolean withTags)
2866 throws IOException {
2867 int length = kv.getLength();
2868 if (!withTags) {
2869 length = kv.getKeyLength() + kv.getValueLength() + KEYVALUE_INFRASTRUCTURE_SIZE;
2870 }
2871
2872 out.write(Bytes.toBytes(length));
2873 out.write(kv.getBuffer(), kv.getOffset(), length);
2874 return length + Bytes.SIZEOF_INT;
2875 }
2876
2877
2878
2879
2880 public static class RowOnlyComparator implements Comparator<KeyValue> {
2881 final KVComparator comparator;
2882
2883 public RowOnlyComparator(final KVComparator c) {
2884 this.comparator = c;
2885 }
2886
2887 public int compare(KeyValue left, KeyValue right) {
2888 return comparator.compareRows(left, right);
2889 }
2890 }
2891
2892
2893
2894
2895
2896
2897
2898 public interface SamePrefixComparator<T> {
2899
2900
2901
2902
2903 int compareIgnoringPrefix(
2904 int commonPrefix, byte[] left, int loffset, int llength, byte[] right, int roffset, int rlength
2905 );
2906 }
2907
2908
2909
2910
2911 public static class RawBytesComparator extends KVComparator {
2912
2913
2914
2915
2916
2917
2918 public String getLegacyKeyComparatorName() {
2919 return "org.apache.hadoop.hbase.util.Bytes$ByteArrayComparator";
2920 }
2921
2922 public int compareFlatKey(byte[] left, int loffset, int llength, byte[] right,
2923 int roffset, int rlength) {
2924 return Bytes.BYTES_RAWCOMPARATOR.compare(left, loffset, llength, right, roffset, rlength);
2925 }
2926
2927 public byte[] calcIndexKey(byte[] lastKeyOfPreviousBlock, byte[] firstKeyInBlock) {
2928 return firstKeyInBlock;
2929 }
2930
2931 }
2932
2933
2934
2935
2936
2937
2938
2939 @Override
2940 public long heapSize() {
2941 int sum = 0;
2942 sum += ClassSize.OBJECT;
2943 sum += ClassSize.REFERENCE;
2944 sum += ClassSize.align(ClassSize.ARRAY);
2945 sum += ClassSize.align(length);
2946 sum += 2 * Bytes.SIZEOF_INT;
2947 sum += Bytes.SIZEOF_LONG;
2948 return ClassSize.align(sum);
2949 }
2950 }