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