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