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.util;
21
22 import org.apache.hadoop.hbase.HConstants;
23 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.io.RawComparator;
27 import org.apache.hadoop.io.WritableComparator;
28 import org.apache.hadoop.io.WritableUtils;
29
30 import java.io.DataInput;
31 import java.io.DataOutput;
32 import java.io.IOException;
33 import java.io.UnsupportedEncodingException;
34 import java.math.BigInteger;
35 import java.nio.ByteBuffer;
36 import java.util.Comparator;
37 import java.util.Iterator;
38 import java.math.BigDecimal;
39
40
41
42
43
44
45 public class Bytes {
46
47 private static final Log LOG = LogFactory.getLog(Bytes.class);
48
49
50
51
52 public static final int SIZEOF_BOOLEAN = Byte.SIZE / Byte.SIZE;
53
54
55
56
57 public static final int SIZEOF_BYTE = SIZEOF_BOOLEAN;
58
59
60
61
62 public static final int SIZEOF_CHAR = Character.SIZE / Byte.SIZE;
63
64
65
66
67 public static final int SIZEOF_DOUBLE = Double.SIZE / Byte.SIZE;
68
69
70
71
72 public static final int SIZEOF_FLOAT = Float.SIZE / Byte.SIZE;
73
74
75
76
77 public static final int SIZEOF_INT = Integer.SIZE / Byte.SIZE;
78
79
80
81
82 public static final int SIZEOF_LONG = Long.SIZE / Byte.SIZE;
83
84
85
86
87 public static final int SIZEOF_SHORT = Short.SIZE / Byte.SIZE;
88
89
90
91
92
93
94
95
96 public static final int ESTIMATED_HEAP_TAX = 16;
97
98
99
100
101 public static class ByteArrayComparator implements RawComparator<byte []> {
102
103
104
105 public ByteArrayComparator() {
106 super();
107 }
108 public int compare(byte [] left, byte [] right) {
109 return compareTo(left, right);
110 }
111 public int compare(byte [] b1, int s1, int l1, byte [] b2, int s2, int l2) {
112 return compareTo(b1, s1, l1, b2, s2, l2);
113 }
114 }
115
116
117
118
119 public static Comparator<byte []> BYTES_COMPARATOR =
120 new ByteArrayComparator();
121
122
123
124
125 public static RawComparator<byte []> BYTES_RAWCOMPARATOR =
126 new ByteArrayComparator();
127
128
129
130
131
132
133
134 public static byte [] readByteArray(final DataInput in)
135 throws IOException {
136 int len = WritableUtils.readVInt(in);
137 if (len < 0) {
138 throw new NegativeArraySizeException(Integer.toString(len));
139 }
140 byte [] result = new byte[len];
141 in.readFully(result, 0, len);
142 return result;
143 }
144
145
146
147
148
149
150
151 public static byte [] readByteArrayThrowsRuntime(final DataInput in) {
152 try {
153 return readByteArray(in);
154 } catch (Exception e) {
155 throw new RuntimeException(e);
156 }
157 }
158
159
160
161
162
163
164
165 public static void writeByteArray(final DataOutput out, final byte [] b)
166 throws IOException {
167 if(b == null) {
168 WritableUtils.writeVInt(out, 0);
169 } else {
170 writeByteArray(out, b, 0, b.length);
171 }
172 }
173
174
175
176
177
178
179
180
181
182 public static void writeByteArray(final DataOutput out, final byte [] b,
183 final int offset, final int length)
184 throws IOException {
185 WritableUtils.writeVInt(out, length);
186 out.write(b, offset, length);
187 }
188
189
190
191
192
193
194
195
196
197
198 public static int writeByteArray(final byte [] tgt, final int tgtOffset,
199 final byte [] src, final int srcOffset, final int srcLength) {
200 byte [] vint = vintToBytes(srcLength);
201 System.arraycopy(vint, 0, tgt, tgtOffset, vint.length);
202 int offset = tgtOffset + vint.length;
203 System.arraycopy(src, srcOffset, tgt, offset, srcLength);
204 return offset + srcLength;
205 }
206
207
208
209
210
211
212
213
214
215
216 public static int putBytes(byte[] tgtBytes, int tgtOffset, byte[] srcBytes,
217 int srcOffset, int srcLength) {
218 System.arraycopy(srcBytes, srcOffset, tgtBytes, tgtOffset, srcLength);
219 return tgtOffset + srcLength;
220 }
221
222
223
224
225
226
227
228
229 public static int putByte(byte[] bytes, int offset, byte b) {
230 bytes[offset] = b;
231 return offset + 1;
232 }
233
234
235
236
237
238
239 public static byte[] toBytes(ByteBuffer bb) {
240 int length = bb.limit();
241 byte [] result = new byte[length];
242 System.arraycopy(bb.array(), bb.arrayOffset(), result, 0, length);
243 return result;
244 }
245
246
247
248
249
250 public static String toString(final byte [] b) {
251 if (b == null) {
252 return null;
253 }
254 return toString(b, 0, b.length);
255 }
256
257
258
259
260
261
262
263 public static String toString(final byte [] b1,
264 String sep,
265 final byte [] b2) {
266 return toString(b1, 0, b1.length) + sep + toString(b2, 0, b2.length);
267 }
268
269
270
271
272
273
274
275
276
277
278
279 public static String toString(final byte [] b, int off, int len) {
280 if (b == null) {
281 return null;
282 }
283 if (len == 0) {
284 return "";
285 }
286 try {
287 return new String(b, off, len, HConstants.UTF8_ENCODING);
288 } catch (UnsupportedEncodingException e) {
289 LOG.error("UTF-8 not supported?", e);
290 return null;
291 }
292 }
293
294
295
296
297
298
299
300
301 public static String toStringBinary(final byte [] b) {
302 return toStringBinary(b, 0, b.length);
303 }
304
305
306
307
308
309
310
311
312
313
314
315 public static String toStringBinary(final byte [] b, int off, int len) {
316 StringBuilder result = new StringBuilder();
317 try {
318 String first = new String(b, off, len, "ISO-8859-1");
319 for (int i = 0; i < first.length() ; ++i ) {
320 int ch = first.charAt(i) & 0xFF;
321 if ( (ch >= '0' && ch <= '9')
322 || (ch >= 'A' && ch <= 'Z')
323 || (ch >= 'a' && ch <= 'z')
324 || " `~!@#$%^&*()-_=+[]{}\\|;:'\",.<>/?".indexOf(ch) >= 0 ) {
325 result.append(first.charAt(i));
326 } else {
327 result.append(String.format("\\x%02X", ch));
328 }
329 }
330 } catch (UnsupportedEncodingException e) {
331 LOG.error("ISO-8859-1 not supported?", e);
332 }
333 return result.toString();
334 }
335
336 private static boolean isHexDigit(char c) {
337 return
338 (c >= 'A' && c <= 'F') ||
339 (c >= '0' && c <= '9');
340 }
341
342
343
344
345
346
347
348 public static byte toBinaryFromHex(byte ch) {
349 if ( ch >= 'A' && ch <= 'F' )
350 return (byte) ((byte)10 + (byte) (ch - 'A'));
351
352 return (byte) (ch - '0');
353 }
354
355 public static byte [] toBytesBinary(String in) {
356
357 byte [] b = new byte[in.length()];
358 int size = 0;
359 for (int i = 0; i < in.length(); ++i) {
360 char ch = in.charAt(i);
361 if (ch == '\\') {
362
363 char next = in.charAt(i+1);
364 if (next != 'x') {
365
366 b[size++] = (byte)ch;
367 continue;
368 }
369
370 char hd1 = in.charAt(i+2);
371 char hd2 = in.charAt(i+3);
372
373
374 if (!isHexDigit(hd1) ||
375 !isHexDigit(hd2)) {
376
377 continue;
378 }
379
380 byte d = (byte) ((toBinaryFromHex((byte)hd1) << 4) + toBinaryFromHex((byte)hd2));
381
382 b[size++] = d;
383 i += 3;
384 } else {
385 b[size++] = (byte) ch;
386 }
387 }
388
389 byte [] b2 = new byte[size];
390 System.arraycopy(b, 0, b2, 0, size);
391 return b2;
392 }
393
394
395
396
397
398
399 public static byte[] toBytes(String s) {
400 try {
401 return s.getBytes(HConstants.UTF8_ENCODING);
402 } catch (UnsupportedEncodingException e) {
403 LOG.error("UTF-8 not supported?", e);
404 return null;
405 }
406 }
407
408
409
410
411
412
413
414
415 public static byte [] toBytes(final boolean b) {
416 return new byte[] { b ? (byte) -1 : (byte) 0 };
417 }
418
419
420
421
422
423
424 public static boolean toBoolean(final byte [] b) {
425 if (b.length != 1) {
426 throw new IllegalArgumentException("Array has wrong size: " + b.length);
427 }
428 return b[0] != (byte) 0;
429 }
430
431
432
433
434
435
436
437 public static byte[] toBytes(long val) {
438 byte [] b = new byte[8];
439 for (int i = 7; i > 0; i--) {
440 b[i] = (byte) val;
441 val >>>= 8;
442 }
443 b[0] = (byte) val;
444 return b;
445 }
446
447
448
449
450
451
452
453 public static long toLong(byte[] bytes) {
454 return toLong(bytes, 0, SIZEOF_LONG);
455 }
456
457
458
459
460
461
462
463
464
465 public static long toLong(byte[] bytes, int offset) {
466 return toLong(bytes, offset, SIZEOF_LONG);
467 }
468
469
470
471
472
473
474
475
476
477
478
479 public static long toLong(byte[] bytes, int offset, final int length) {
480 if (length != SIZEOF_LONG || offset + length > bytes.length) {
481 throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_LONG);
482 }
483 long l = 0;
484 for(int i = offset; i < offset + length; i++) {
485 l <<= 8;
486 l ^= bytes[i] & 0xFF;
487 }
488 return l;
489 }
490
491 private static IllegalArgumentException
492 explainWrongLengthOrOffset(final byte[] bytes,
493 final int offset,
494 final int length,
495 final int expectedLength) {
496 String reason;
497 if (length != expectedLength) {
498 reason = "Wrong length: " + length + ", expected " + expectedLength;
499 } else {
500 reason = "offset (" + offset + ") + length (" + length + ") exceed the"
501 + " capacity of the array: " + bytes.length;
502 }
503 return new IllegalArgumentException(reason);
504 }
505
506
507
508
509
510
511
512
513
514
515 public static int putLong(byte[] bytes, int offset, long val) {
516 if (bytes.length - offset < SIZEOF_LONG) {
517 throw new IllegalArgumentException("Not enough room to put a long at"
518 + " offset " + offset + " in a " + bytes.length + " byte array");
519 }
520 for(int i = offset + 7; i > offset; i--) {
521 bytes[i] = (byte) val;
522 val >>>= 8;
523 }
524 bytes[offset] = (byte) val;
525 return offset + SIZEOF_LONG;
526 }
527
528
529
530
531
532
533 public static float toFloat(byte [] bytes) {
534 return toFloat(bytes, 0);
535 }
536
537
538
539
540
541
542
543 public static float toFloat(byte [] bytes, int offset) {
544 return Float.intBitsToFloat(toInt(bytes, offset, SIZEOF_INT));
545 }
546
547
548
549
550
551
552
553 public static int putFloat(byte [] bytes, int offset, float f) {
554 return putInt(bytes, offset, Float.floatToRawIntBits(f));
555 }
556
557
558
559
560
561 public static byte [] toBytes(final float f) {
562
563 return Bytes.toBytes(Float.floatToRawIntBits(f));
564 }
565
566
567
568
569
570 public static double toDouble(final byte [] bytes) {
571 return toDouble(bytes, 0);
572 }
573
574
575
576
577
578
579 public static double toDouble(final byte [] bytes, final int offset) {
580 return Double.longBitsToDouble(toLong(bytes, offset, SIZEOF_LONG));
581 }
582
583
584
585
586
587
588
589 public static int putDouble(byte [] bytes, int offset, double d) {
590 return putLong(bytes, offset, Double.doubleToLongBits(d));
591 }
592
593
594
595
596
597
598
599
600 public static byte [] toBytes(final double d) {
601
602 return Bytes.toBytes(Double.doubleToRawLongBits(d));
603 }
604
605
606
607
608
609
610 public static byte[] toBytes(int val) {
611 byte [] b = new byte[4];
612 for(int i = 3; i > 0; i--) {
613 b[i] = (byte) val;
614 val >>>= 8;
615 }
616 b[0] = (byte) val;
617 return b;
618 }
619
620
621
622
623
624
625 public static int toInt(byte[] bytes) {
626 return toInt(bytes, 0, SIZEOF_INT);
627 }
628
629
630
631
632
633
634
635 public static int toInt(byte[] bytes, int offset) {
636 return toInt(bytes, offset, SIZEOF_INT);
637 }
638
639
640
641
642
643
644
645
646
647
648 public static int toInt(byte[] bytes, int offset, final int length) {
649 if (length != SIZEOF_INT || offset + length > bytes.length) {
650 throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_INT);
651 }
652 int n = 0;
653 for(int i = offset; i < (offset + length); i++) {
654 n <<= 8;
655 n ^= bytes[i] & 0xFF;
656 }
657 return n;
658 }
659
660
661
662
663
664
665
666
667
668
669 public static int putInt(byte[] bytes, int offset, int val) {
670 if (bytes.length - offset < SIZEOF_INT) {
671 throw new IllegalArgumentException("Not enough room to put an int at"
672 + " offset " + offset + " in a " + bytes.length + " byte array");
673 }
674 for(int i= offset + 3; i > offset; i--) {
675 bytes[i] = (byte) val;
676 val >>>= 8;
677 }
678 bytes[offset] = (byte) val;
679 return offset + SIZEOF_INT;
680 }
681
682
683
684
685
686
687 public static byte[] toBytes(short val) {
688 byte[] b = new byte[SIZEOF_SHORT];
689 b[1] = (byte) val;
690 val >>= 8;
691 b[0] = (byte) val;
692 return b;
693 }
694
695
696
697
698
699
700 public static short toShort(byte[] bytes) {
701 return toShort(bytes, 0, SIZEOF_SHORT);
702 }
703
704
705
706
707
708
709
710 public static short toShort(byte[] bytes, int offset) {
711 return toShort(bytes, offset, SIZEOF_SHORT);
712 }
713
714
715
716
717
718
719
720
721
722
723 public static short toShort(byte[] bytes, int offset, final int length) {
724 if (length != SIZEOF_SHORT || offset + length > bytes.length) {
725 throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT);
726 }
727 short n = 0;
728 n ^= bytes[offset] & 0xFF;
729 n <<= 8;
730 n ^= bytes[offset+1] & 0xFF;
731 return n;
732 }
733
734
735
736
737
738
739
740
741
742
743 public static int putShort(byte[] bytes, int offset, short val) {
744 if (bytes.length - offset < SIZEOF_SHORT) {
745 throw new IllegalArgumentException("Not enough room to put a short at"
746 + " offset " + offset + " in a " + bytes.length + " byte array");
747 }
748 bytes[offset+1] = (byte) val;
749 val >>= 8;
750 bytes[offset] = (byte) val;
751 return offset + SIZEOF_SHORT;
752 }
753
754
755
756
757
758
759
760 public static byte[] toBytes(BigDecimal val) {
761 byte[] valueBytes = val.unscaledValue().toByteArray();
762 byte[] result = new byte[valueBytes.length + SIZEOF_INT];
763 int offset = putInt(result, 0, val.scale());
764 putBytes(result, offset, valueBytes, 0, valueBytes.length);
765 return result;
766 }
767
768
769
770
771
772
773
774
775 public static BigDecimal toBigDecimal(byte[] bytes) {
776 return toBigDecimal(bytes, 0, bytes.length);
777 }
778
779
780
781
782
783
784
785
786 public static BigDecimal toBigDecimal(byte[] bytes, int offset) {
787 return toBigDecimal(bytes, offset, bytes.length);
788 }
789
790
791
792
793
794
795
796
797
798 public static BigDecimal toBigDecimal(byte[] bytes, int offset, final int length) {
799 if (bytes == null || length < SIZEOF_INT + 1 ||
800 (offset + length > bytes.length)) {
801 return null;
802 }
803
804 int scale = toInt(bytes, 0);
805 byte[] tcBytes = new byte[length - SIZEOF_INT];
806 System.arraycopy(bytes, SIZEOF_INT, tcBytes, 0, length - SIZEOF_INT);
807 return new BigDecimal(new BigInteger(tcBytes), scale);
808 }
809
810
811
812
813
814
815
816
817
818 public static int putBigDecimal(byte[] bytes, int offset, BigDecimal val) {
819 if (bytes == null) {
820 return offset;
821 }
822
823 byte[] valueBytes = val.unscaledValue().toByteArray();
824 byte[] result = new byte[valueBytes.length + SIZEOF_INT];
825 offset = putInt(result, offset, val.scale());
826 return putBytes(result, offset, valueBytes, 0, valueBytes.length);
827 }
828
829
830
831
832
833 public static byte [] vintToBytes(final long vint) {
834 long i = vint;
835 int size = WritableUtils.getVIntSize(i);
836 byte [] result = new byte[size];
837 int offset = 0;
838 if (i >= -112 && i <= 127) {
839 result[offset] = (byte) i;
840 return result;
841 }
842
843 int len = -112;
844 if (i < 0) {
845 i ^= -1L;
846 len = -120;
847 }
848
849 long tmp = i;
850 while (tmp != 0) {
851 tmp = tmp >> 8;
852 len--;
853 }
854
855 result[offset++] = (byte) len;
856
857 len = (len < -120) ? -(len + 120) : -(len + 112);
858
859 for (int idx = len; idx != 0; idx--) {
860 int shiftbits = (idx - 1) * 8;
861 long mask = 0xFFL << shiftbits;
862 result[offset++] = (byte)((i & mask) >> shiftbits);
863 }
864 return result;
865 }
866
867
868
869
870
871 public static long bytesToVint(final byte [] buffer) {
872 int offset = 0;
873 byte firstByte = buffer[offset++];
874 int len = WritableUtils.decodeVIntSize(firstByte);
875 if (len == 1) {
876 return firstByte;
877 }
878 long i = 0;
879 for (int idx = 0; idx < len-1; idx++) {
880 byte b = buffer[offset++];
881 i = i << 8;
882 i = i | (b & 0xFF);
883 }
884 return (WritableUtils.isNegativeVInt(firstByte) ? ~i : i);
885 }
886
887
888
889
890
891
892
893
894 public static long readVLong(final byte [] buffer, final int offset)
895 throws IOException {
896 byte firstByte = buffer[offset];
897 int len = WritableUtils.decodeVIntSize(firstByte);
898 if (len == 1) {
899 return firstByte;
900 }
901 long i = 0;
902 for (int idx = 0; idx < len-1; idx++) {
903 byte b = buffer[offset + 1 + idx];
904 i = i << 8;
905 i = i | (b & 0xFF);
906 }
907 return (WritableUtils.isNegativeVInt(firstByte) ? ~i : i);
908 }
909
910
911
912
913
914
915 public static int compareTo(final byte [] left, final byte [] right) {
916 return compareTo(left, 0, left.length, right, 0, right.length);
917 }
918
919
920
921
922
923
924
925
926
927
928
929
930 public static int compareTo(byte[] buffer1, int offset1, int length1,
931 byte[] buffer2, int offset2, int length2) {
932
933 int end1 = offset1 + length1;
934 int end2 = offset2 + length2;
935 for (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) {
936 int a = (buffer1[i] & 0xff);
937 int b = (buffer2[j] & 0xff);
938 if (a != b) {
939 return a - b;
940 }
941 }
942 return length1 - length2;
943 }
944
945
946
947
948
949
950 public static boolean equals(final byte [] left, final byte [] right) {
951
952
953 if (left == null && right == null) {
954 return true;
955 }
956 return (left == null || right == null || (left.length != right.length)
957 ? false : compareTo(left, right) == 0);
958 }
959
960
961
962
963
964 public static boolean startsWith(byte[] bytes, byte[] prefix) {
965 return bytes != null && prefix != null &&
966 bytes.length >= prefix.length &&
967 compareTo(bytes, 0, prefix.length, prefix, 0, prefix.length) == 0;
968 }
969
970
971
972
973
974
975
976 public static int hashCode(final byte [] b) {
977 return hashCode(b, b.length);
978 }
979
980
981
982
983
984
985
986
987 public static int hashCode(final byte [] b, final int length) {
988 return WritableComparator.hashBytes(b, length);
989 }
990
991
992
993
994
995
996 public static Integer mapKey(final byte [] b) {
997 return hashCode(b);
998 }
999
1000
1001
1002
1003
1004
1005
1006 public static Integer mapKey(final byte [] b, final int length) {
1007 return hashCode(b, length);
1008 }
1009
1010
1011
1012
1013
1014
1015 public static byte [] add(final byte [] a, final byte [] b) {
1016 return add(a, b, HConstants.EMPTY_BYTE_ARRAY);
1017 }
1018
1019
1020
1021
1022
1023
1024
1025 public static byte [] add(final byte [] a, final byte [] b, final byte [] c) {
1026 byte [] result = new byte[a.length + b.length + c.length];
1027 System.arraycopy(a, 0, result, 0, a.length);
1028 System.arraycopy(b, 0, result, a.length, b.length);
1029 System.arraycopy(c, 0, result, a.length + b.length, c.length);
1030 return result;
1031 }
1032
1033
1034
1035
1036
1037
1038 public static byte [] head(final byte [] a, final int length) {
1039 if (a.length < length) {
1040 return null;
1041 }
1042 byte [] result = new byte[length];
1043 System.arraycopy(a, 0, result, 0, length);
1044 return result;
1045 }
1046
1047
1048
1049
1050
1051
1052 public static byte [] tail(final byte [] a, final int length) {
1053 if (a.length < length) {
1054 return null;
1055 }
1056 byte [] result = new byte[length];
1057 System.arraycopy(a, a.length - length, result, 0, length);
1058 return result;
1059 }
1060
1061
1062
1063
1064
1065
1066 public static byte [] padHead(final byte [] a, final int length) {
1067 byte [] padding = new byte[length];
1068 for (int i = 0; i < length; i++) {
1069 padding[i] = 0;
1070 }
1071 return add(padding,a);
1072 }
1073
1074
1075
1076
1077
1078
1079 public static byte [] padTail(final byte [] a, final int length) {
1080 byte [] padding = new byte[length];
1081 for (int i = 0; i < length; i++) {
1082 padding[i] = 0;
1083 }
1084 return add(a,padding);
1085 }
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096 public static byte [][] split(final byte [] a, final byte [] b, final int num) {
1097 byte[][] ret = new byte[num+2][];
1098 int i = 0;
1099 Iterable<byte[]> iter = iterateOnSplits(a, b, num);
1100 if (iter == null) return null;
1101 for (byte[] elem : iter) {
1102 ret[i++] = elem;
1103 }
1104 return ret;
1105 }
1106
1107
1108
1109
1110 public static Iterable<byte[]> iterateOnSplits(
1111 final byte[] a, final byte[]b, final int num)
1112 {
1113 byte [] aPadded;
1114 byte [] bPadded;
1115 if (a.length < b.length) {
1116 aPadded = padTail(a, b.length - a.length);
1117 bPadded = b;
1118 } else if (b.length < a.length) {
1119 aPadded = a;
1120 bPadded = padTail(b, a.length - b.length);
1121 } else {
1122 aPadded = a;
1123 bPadded = b;
1124 }
1125 if (compareTo(aPadded,bPadded) >= 0) {
1126 throw new IllegalArgumentException("b <= a");
1127 }
1128 if (num <= 0) {
1129 throw new IllegalArgumentException("num cannot be < 0");
1130 }
1131 byte [] prependHeader = {1, 0};
1132 final BigInteger startBI = new BigInteger(add(prependHeader, aPadded));
1133 final BigInteger stopBI = new BigInteger(add(prependHeader, bPadded));
1134 final BigInteger diffBI = stopBI.subtract(startBI);
1135 final BigInteger splitsBI = BigInteger.valueOf(num + 1);
1136 if(diffBI.compareTo(splitsBI) < 0) {
1137 return null;
1138 }
1139 final BigInteger intervalBI;
1140 try {
1141 intervalBI = diffBI.divide(splitsBI);
1142 } catch(Exception e) {
1143 LOG.error("Exception caught during division", e);
1144 return null;
1145 }
1146
1147 final Iterator<byte[]> iterator = new Iterator<byte[]>() {
1148 private int i = -1;
1149
1150 @Override
1151 public boolean hasNext() {
1152 return i < num+1;
1153 }
1154
1155 @Override
1156 public byte[] next() {
1157 i++;
1158 if (i == 0) return a;
1159 if (i == num + 1) return b;
1160
1161 BigInteger curBI = startBI.add(intervalBI.multiply(BigInteger.valueOf(i)));
1162 byte [] padded = curBI.toByteArray();
1163 if (padded[1] == 0)
1164 padded = tail(padded, padded.length - 2);
1165 else
1166 padded = tail(padded, padded.length - 1);
1167 return padded;
1168 }
1169
1170 @Override
1171 public void remove() {
1172 throw new UnsupportedOperationException();
1173 }
1174
1175 };
1176
1177 return new Iterable<byte[]>() {
1178 @Override
1179 public Iterator<byte[]> iterator() {
1180 return iterator;
1181 }
1182 };
1183 }
1184
1185
1186
1187
1188
1189 public static byte [][] toByteArrays(final String [] t) {
1190 byte [][] result = new byte[t.length][];
1191 for (int i = 0; i < t.length; i++) {
1192 result[i] = Bytes.toBytes(t[i]);
1193 }
1194 return result;
1195 }
1196
1197
1198
1199
1200
1201
1202 public static byte [][] toByteArrays(final String column) {
1203 return toByteArrays(toBytes(column));
1204 }
1205
1206
1207
1208
1209
1210
1211 public static byte [][] toByteArrays(final byte [] column) {
1212 byte [][] result = new byte[1][];
1213 result[0] = column;
1214 return result;
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226 public static int binarySearch(byte [][]arr, byte []key, int offset,
1227 int length, RawComparator<byte []> comparator) {
1228 int low = 0;
1229 int high = arr.length - 1;
1230
1231 while (low <= high) {
1232 int mid = (low+high) >>> 1;
1233
1234
1235 int cmp = comparator.compare(key, offset, length,
1236 arr[mid], 0, arr[mid].length);
1237
1238 if (cmp > 0)
1239 low = mid + 1;
1240
1241 else if (cmp < 0)
1242 high = mid - 1;
1243
1244 else
1245 return mid;
1246 }
1247 return - (low+1);
1248 }
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 public static byte [] incrementBytes(byte[] value, long amount)
1260 throws IOException {
1261 byte[] val = value;
1262 if (val.length < SIZEOF_LONG) {
1263
1264 byte [] newvalue;
1265 if (val[0] < 0) {
1266 newvalue = new byte[]{-1, -1, -1, -1, -1, -1, -1, -1};
1267 } else {
1268 newvalue = new byte[SIZEOF_LONG];
1269 }
1270 System.arraycopy(val, 0, newvalue, newvalue.length - val.length,
1271 val.length);
1272 val = newvalue;
1273 } else if (val.length > SIZEOF_LONG) {
1274 throw new IllegalArgumentException("Increment Bytes - value too big: " +
1275 val.length);
1276 }
1277 if(amount == 0) return val;
1278 if(val[0] < 0){
1279 return binaryIncrementNeg(val, amount);
1280 }
1281 return binaryIncrementPos(val, amount);
1282 }
1283
1284
1285 private static byte [] binaryIncrementPos(byte [] value, long amount) {
1286 long amo = amount;
1287 int sign = 1;
1288 if (amount < 0) {
1289 amo = -amount;
1290 sign = -1;
1291 }
1292 for(int i=0;i<value.length;i++) {
1293 int cur = ((int)amo % 256) * sign;
1294 amo = (amo >> 8);
1295 int val = value[value.length-i-1] & 0x0ff;
1296 int total = val + cur;
1297 if(total > 255) {
1298 amo += sign;
1299 total %= 256;
1300 } else if (total < 0) {
1301 amo -= sign;
1302 }
1303 value[value.length-i-1] = (byte)total;
1304 if (amo == 0) return value;
1305 }
1306 return value;
1307 }
1308
1309
1310 private static byte [] binaryIncrementNeg(byte [] value, long amount) {
1311 long amo = amount;
1312 int sign = 1;
1313 if (amount < 0) {
1314 amo = -amount;
1315 sign = -1;
1316 }
1317 for(int i=0;i<value.length;i++) {
1318 int cur = ((int)amo % 256) * sign;
1319 amo = (amo >> 8);
1320 int val = ((~value[value.length-i-1]) & 0x0ff) + 1;
1321 int total = cur - val;
1322 if(total >= 0) {
1323 amo += sign;
1324 } else if (total < -256) {
1325 amo -= sign;
1326 total %= 256;
1327 }
1328 value[value.length-i-1] = (byte)total;
1329 if (amo == 0) return value;
1330 }
1331 return value;
1332 }
1333
1334 }