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