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