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