1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.util;
19
20 import static org.junit.Assert.assertArrayEquals;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.fail;
23
24 import java.math.BigDecimal;
25 import java.util.Arrays;
26 import java.util.Collections;
27
28 import org.apache.hadoop.hbase.SmallTests;
29 import org.junit.Test;
30 import org.junit.experimental.categories.Category;
31
32 @Category(SmallTests.class)
33 public class TestOrderedBytes {
34
35
36 static final Long[] I_VALS =
37 { 0L, 1L, 10L, 99L, 100L, 1234L, 9999L, 10000L, 10001L, 12345L, 123450L, Long.MAX_VALUE,
38 -1L, -10L, -99L, -100L, -123L, -999L, -10000L, -10001L, -12345L, -123450L, Long.MIN_VALUE };
39 static final int[] I_LENGTHS =
40 { 1, 2, 2, 2, 2, 3, 3, 2, 4, 4, 4, 11, 2, 2, 2, 2, 3, 3, 2, 4, 4, 4, 11 };
41
42
43 static final Double[] D_VALS =
44 { 0.0, 0.00123, 0.0123, 0.123, 1.0, 10.0, 12.345, 99.0, 99.01, 99.0001, 100.0, 100.01,
45 100.1, 1234.0, 1234.5, 9999.0, 9999.000001, 9999.000009, 9999.00001, 9999.00009,
46 9999.000099, 9999.0001, 9999.001, 9999.01, 9999.1, 10000.0, 10001.0, 12345.0, 123450.0,
47 Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN, Double.MAX_VALUE,
48 -0.00123, -0.0123, -0.123, -1.0, -10.0, -12.345, -99.0, -99.01, -99.0001, -100.0, -100.01,
49 -100.1, -1234.0, -1234.5, -9999.0, -9999.000001, -9999.000009, -9999.00001, -9999.00009,
50 -9999.000099, -9999.0001, -9999.001, -9999.01, -9999.1, -10000.0, -10001.0, -12345.0,
51 -123450.0 };
52 static final int[] D_LENGTHS =
53 { 1, 4, 4, 4, 2, 2, 4, 2, 3, 4, 2, 4,
54 4, 3, 4, 3, 6, 6, 6, 6,
55 6, 5, 5, 4, 4, 2, 4, 4, 4,
56 1, 1, 1, 11,
57 4, 4, 4, 2, 2, 4, 2, 3, 4, 2, 4,
58 4, 3, 4, 3, 6, 6, 6, 6,
59 6, 5, 5, 4, 4, 2, 4, 4,
60 4 };
61
62
63 static final BigDecimal[] BD_VALS =
64 { null, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MIN_VALUE),
65 BigDecimal.valueOf(Double.MAX_VALUE), BigDecimal.valueOf(Double.MIN_VALUE),
66 BigDecimal.valueOf(Long.MAX_VALUE).multiply(BigDecimal.valueOf(100)) };
67 static final int[] BD_LENGTHS =
68 { 1, 11, 11, 11, 4, 12 };
69
70
71
72
73 static final double MIN_EPSILON = 0.000001;
74
75
76
77
78 @Test
79 public void testVerifyTestIntegrity() {
80 for (int i = 0; i < I_VALS.length; i++) {
81 for (int d = 0; d < D_VALS.length; d++) {
82 if (Math.abs(I_VALS[i] - D_VALS[d]) < MIN_EPSILON) {
83 assertEquals(
84 "Test inconsistency detected: expected lengths for " + I_VALS[i] + " do not match.",
85 I_LENGTHS[i], D_LENGTHS[d]);
86 }
87 }
88 }
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110 @Test
111 public void testVaruint64Boundaries() {
112 long vals[] =
113 { 239L, 240L, 2286L, 2287L, 67822L, 67823L, 16777214L, 16777215L, 4294967294L, 4294967295L,
114 1099511627774L, 1099511627775L, 281474976710654L, 281474976710655L, 72057594037927934L,
115 72057594037927935L, Long.MAX_VALUE - 1, Long.MAX_VALUE, Long.MIN_VALUE + 1,
116 Long.MIN_VALUE, -2L, -1L };
117 int lens[] = { 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 };
118 assertEquals("Broken test!", vals.length, lens.length);
119
120
121
122
123
124 for (boolean comp : new boolean[] { true, false }) {
125 for (int i = 0; i < vals.length; i++) {
126
127 byte[] a = new byte[lens[i] + 2];
128 PositionedByteRange buf = new SimplePositionedByteRange(a, 1, lens[i]);
129
130
131 assertEquals("Surprising return value.",
132 lens[i], OrderedBytes.putVaruint64(buf, vals[i], comp));
133 assertEquals("Surprising serialized length.", lens[i], buf.getPosition());
134 assertEquals("Buffer underflow.", 0, a[0]);
135 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
136
137
138 buf.setPosition(0);
139 assertEquals("Surprising return value.",
140 lens[i], OrderedBytes.skipVaruint64(buf, comp));
141 assertEquals("Did not skip enough bytes.", lens[i], buf.getPosition());
142
143
144 buf.setPosition(0);
145 assertEquals("Deserialization failed.", vals[i], OrderedBytes.getVaruint64(buf, comp));
146 assertEquals("Did not consume enough bytes.", lens[i], buf.getPosition());
147 }
148 }
149 }
150
151
152
153
154
155 @Test
156 public void testNumericInt() {
157
158
159
160
161 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
162 for (int i = 0; i < I_VALS.length; i++) {
163
164 byte[] a = new byte[I_LENGTHS[i] + 2];
165 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, I_LENGTHS[i]);
166
167
168 assertEquals("Surprising return value.",
169 I_LENGTHS[i], OrderedBytes.encodeNumeric(buf1, I_VALS[i], ord));
170 assertEquals("Surprising serialized length.", I_LENGTHS[i], buf1.getPosition());
171 assertEquals("Buffer underflow.", 0, a[0]);
172 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
173
174
175 buf1.setPosition(0);
176 assertEquals("Surprising return value.", I_LENGTHS[i], OrderedBytes.skip(buf1));
177 assertEquals("Did not skip enough bytes.", I_LENGTHS[i], buf1.getPosition());
178
179
180 buf1.setPosition(0);
181 assertEquals("Deserialization failed.",
182 I_VALS[i].longValue(), OrderedBytes.decodeNumericAsLong(buf1));
183 assertEquals("Did not consume enough bytes.", I_LENGTHS[i], buf1.getPosition());
184 }
185 }
186
187
188
189
190 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
191 byte[][] encoded = new byte[I_VALS.length][];
192 PositionedByteRange pbr = new SimplePositionedByteRange();
193 for (int i = 0; i < I_VALS.length; i++) {
194 encoded[i] = new byte[I_LENGTHS[i]];
195 OrderedBytes.encodeNumeric(pbr.set(encoded[i]), I_VALS[i], ord);
196 }
197
198 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
199 Long[] sortedVals = Arrays.copyOf(I_VALS, I_VALS.length);
200 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
201 else Arrays.sort(sortedVals, Collections.reverseOrder());
202
203 for (int i = 0; i < sortedVals.length; i++) {
204 pbr.set(encoded[i]);
205 long decoded = OrderedBytes.decodeNumericAsLong(pbr);
206 assertEquals(
207 String.format(
208 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
209 sortedVals[i], decoded, ord),
210 sortedVals[i].longValue(), decoded);
211 }
212 }
213 }
214
215
216
217
218 @Test
219 public void testNumericReal() {
220
221
222
223
224 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
225 for (int i = 0; i < D_VALS.length; i++) {
226
227 byte[] a = new byte[D_LENGTHS[i] + 2];
228 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, D_LENGTHS[i]);
229
230
231 assertEquals("Surprising return value.",
232 D_LENGTHS[i], OrderedBytes.encodeNumeric(buf1, D_VALS[i], ord));
233 assertEquals("Surprising serialized length.", D_LENGTHS[i], buf1.getPosition());
234 assertEquals("Buffer underflow.", 0, a[0]);
235 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
236
237
238 buf1.setPosition(0);
239 assertEquals("Surprising return value.", D_LENGTHS[i], OrderedBytes.skip(buf1));
240 assertEquals("Did not skip enough bytes.", D_LENGTHS[i], buf1.getPosition());
241
242
243 buf1.setPosition(0);
244 assertEquals("Deserialization failed.",
245 D_VALS[i].doubleValue(), OrderedBytes.decodeNumericAsDouble(buf1), MIN_EPSILON);
246 assertEquals("Did not consume enough bytes.", D_LENGTHS[i], buf1.getPosition());
247 }
248 }
249
250
251
252
253 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
254 byte[][] encoded = new byte[D_VALS.length][];
255 PositionedByteRange pbr = new SimplePositionedByteRange();
256 for (int i = 0; i < D_VALS.length; i++) {
257 encoded[i] = new byte[D_LENGTHS[i]];
258 OrderedBytes.encodeNumeric(pbr.set(encoded[i]), D_VALS[i], ord);
259 }
260
261 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
262 Double[] sortedVals = Arrays.copyOf(D_VALS, D_VALS.length);
263 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
264 else Arrays.sort(sortedVals, Collections.reverseOrder());
265
266 for (int i = 0; i < sortedVals.length; i++) {
267 pbr.set(encoded[i]);
268 double decoded = OrderedBytes.decodeNumericAsDouble(pbr);
269 assertEquals(
270 String.format(
271 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
272 sortedVals[i], decoded, ord),
273 sortedVals[i].doubleValue(), decoded, MIN_EPSILON);
274 }
275 }
276 }
277
278
279
280
281 @Test
282 public void testNumericOther() {
283
284
285
286
287 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
288 for (int i = 0; i < BD_VALS.length; i++) {
289
290 byte[] a = new byte[BD_LENGTHS[i] + 2];
291 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, BD_LENGTHS[i]);
292
293
294 assertEquals("Surprising return value.",
295 BD_LENGTHS[i], OrderedBytes.encodeNumeric(buf1, BD_VALS[i], ord));
296 assertEquals("Surprising serialized length.", BD_LENGTHS[i], buf1.getPosition());
297 assertEquals("Buffer underflow.", 0, a[0]);
298 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
299
300
301 buf1.setPosition(0);
302 assertEquals("Surprising return value.", BD_LENGTHS[i], OrderedBytes.skip(buf1));
303 assertEquals("Did not skip enough bytes.", BD_LENGTHS[i], buf1.getPosition());
304
305
306 buf1.setPosition(0);
307 BigDecimal decoded = OrderedBytes.decodeNumericAsBigDecimal(buf1);
308 if (null == BD_VALS[i]) {
309 assertEquals(BD_VALS[i], decoded);
310 } else {
311 assertEquals("Deserialization failed.", 0, BD_VALS[i].compareTo(decoded));
312 }
313 assertEquals("Did not consume enough bytes.", BD_LENGTHS[i], buf1.getPosition());
314 }
315 }
316 }
317
318
319
320
321 @Test
322 public void testNumericIntRealCompatibility() {
323 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
324 for (int i = 0; i < I_VALS.length; i++) {
325
326 PositionedByteRange pbri = new SimplePositionedByteRange(I_LENGTHS[i]);
327 PositionedByteRange pbrr = new SimplePositionedByteRange(I_LENGTHS[i]);
328 OrderedBytes.encodeNumeric(pbri, I_VALS[i], ord);
329 OrderedBytes.encodeNumeric(pbrr, I_VALS[i], ord);
330 assertArrayEquals("Integer and real encodings differ.", pbri.getBytes(), pbrr.getBytes());
331 pbri.setPosition(0);
332 pbrr.setPosition(0);
333 assertEquals((long) I_VALS[i], OrderedBytes.decodeNumericAsLong(pbri));
334 assertEquals((long) I_VALS[i], (long) OrderedBytes.decodeNumericAsDouble(pbrr));
335
336
337 BigDecimal bd = BigDecimal.valueOf(I_VALS[i]);
338 PositionedByteRange pbrbd = new SimplePositionedByteRange(I_LENGTHS[i]);
339 OrderedBytes.encodeNumeric(pbrbd, bd, ord);
340 assertArrayEquals("Integer and BigDecimal encodings differ.",
341 pbri.getBytes(), pbrbd.getBytes());
342 pbri.setPosition(0);
343 assertEquals("Value not preserved when decoding as Long",
344 0, bd.compareTo(BigDecimal.valueOf(OrderedBytes.decodeNumericAsLong(pbri))));
345 }
346 }
347 }
348
349
350
351
352 @Test
353 public void testInt32() {
354 Integer[] vals =
355 { Integer.MIN_VALUE, Integer.MIN_VALUE / 2, 0, Integer.MAX_VALUE / 2, Integer.MAX_VALUE };
356
357
358
359
360
361 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
362 for (int i = 0; i < vals.length; i++) {
363
364 byte[] a = new byte[5 + 2];
365 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, 5);
366
367
368 assertEquals("Surprising return value.",
369 5, OrderedBytes.encodeInt32(buf1, vals[i], ord));
370 assertEquals("Surprising serialized length.", 5, buf1.getPosition());
371 assertEquals("Buffer underflow.", 0, a[0]);
372 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
373
374
375 buf1.setPosition(0);
376 assertEquals("Surprising return value.", 5, OrderedBytes.skip(buf1));
377 assertEquals("Did not skip enough bytes.", 5, buf1.getPosition());
378
379
380 buf1.setPosition(0);
381 assertEquals("Deserialization failed.",
382 vals[i].intValue(), OrderedBytes.decodeInt32(buf1));
383 assertEquals("Did not consume enough bytes.", 5, buf1.getPosition());
384 }
385 }
386
387
388
389
390 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
391 byte[][] encoded = new byte[vals.length][5];
392 PositionedByteRange pbr = new SimplePositionedByteRange();
393 for (int i = 0; i < vals.length; i++) {
394 OrderedBytes.encodeInt32(pbr.set(encoded[i]), vals[i], ord);
395 }
396
397 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
398 Integer[] sortedVals = Arrays.copyOf(vals, vals.length);
399 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
400 else Arrays.sort(sortedVals, Collections.reverseOrder());
401
402 for (int i = 0; i < sortedVals.length; i++) {
403 int decoded = OrderedBytes.decodeInt32(pbr.set(encoded[i]));
404 assertEquals(
405 String.format(
406 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
407 sortedVals[i], decoded, ord),
408 sortedVals[i].intValue(), decoded);
409 }
410 }
411 }
412
413
414
415
416 @Test
417 public void testInt64() {
418 Long[] vals = { Long.MIN_VALUE, Long.MIN_VALUE / 2, 0L, Long.MAX_VALUE / 2, Long.MAX_VALUE };
419
420
421
422
423
424 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
425 for (int i = 0; i < vals.length; i++) {
426
427 byte[] a = new byte[9 + 2];
428 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, 9);
429
430
431 assertEquals("Surprising return value.",
432 9, OrderedBytes.encodeInt64(buf1, vals[i], ord));
433 assertEquals("Surprising serialized length.", 9, buf1.getPosition());
434 assertEquals("Buffer underflow.", 0, a[0]);
435 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
436
437
438 buf1.setPosition(0);
439 assertEquals("Surprising return value.", 9, OrderedBytes.skip(buf1));
440 assertEquals("Did not skip enough bytes.", 9, buf1.getPosition());
441
442
443 buf1.setPosition(0);
444 assertEquals("Deserialization failed.",
445 vals[i].longValue(), OrderedBytes.decodeInt64(buf1));
446 assertEquals("Did not consume enough bytes.", 9, buf1.getPosition());
447 }
448 }
449
450
451
452
453 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
454 byte[][] encoded = new byte[vals.length][9];
455 PositionedByteRange pbr = new SimplePositionedByteRange();
456 for (int i = 0; i < vals.length; i++) {
457 OrderedBytes.encodeInt64(pbr.set(encoded[i]), vals[i], ord);
458 }
459
460 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
461 Long[] sortedVals = Arrays.copyOf(vals, vals.length);
462 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
463 else Arrays.sort(sortedVals, Collections.reverseOrder());
464
465 for (int i = 0; i < sortedVals.length; i++) {
466 long decoded = OrderedBytes.decodeInt64(pbr.set(encoded[i]));
467 assertEquals(
468 String.format(
469 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
470 sortedVals[i], decoded, ord),
471 sortedVals[i].longValue(), decoded);
472 }
473 }
474 }
475
476
477
478
479 @Test
480 public void testFloat32() {
481 Float[] vals =
482 { Float.MIN_VALUE, Float.MIN_VALUE + 1.0f, 0.0f, Float.MAX_VALUE / 2.0f, Float.MAX_VALUE };
483
484
485
486
487
488 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
489 for (int i = 0; i < vals.length; i++) {
490
491 byte[] a = new byte[5 + 2];
492 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, 5);
493
494
495 assertEquals("Surprising return value.",
496 5, OrderedBytes.encodeFloat32(buf1, vals[i], ord));
497 assertEquals("Surprising serialized length.", 5, buf1.getPosition());
498 assertEquals("Buffer underflow.", 0, a[0]);
499 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
500
501
502 buf1.setPosition(0);
503 assertEquals("Surprising return value.", 5, OrderedBytes.skip(buf1));
504 assertEquals("Did not skip enough bytes.", 5, buf1.getPosition());
505
506
507 buf1.setPosition(0);
508 assertEquals("Deserialization failed.",
509 Float.floatToIntBits(vals[i].floatValue()),
510 Float.floatToIntBits(OrderedBytes.decodeFloat32(buf1)));
511 assertEquals("Did not consume enough bytes.", 5, buf1.getPosition());
512 }
513 }
514
515
516
517
518 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
519 byte[][] encoded = new byte[vals.length][5];
520 PositionedByteRange pbr = new SimplePositionedByteRange();
521 for (int i = 0; i < vals.length; i++) {
522 OrderedBytes.encodeFloat32(pbr.set(encoded[i]), vals[i], ord);
523 }
524
525 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
526 Float[] sortedVals = Arrays.copyOf(vals, vals.length);
527 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
528 else Arrays.sort(sortedVals, Collections.reverseOrder());
529
530 for (int i = 0; i < sortedVals.length; i++) {
531 float decoded = OrderedBytes.decodeFloat32(pbr.set(encoded[i]));
532 assertEquals(
533 String.format(
534 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
535 sortedVals[i], decoded, ord),
536 Float.floatToIntBits(sortedVals[i].floatValue()),
537 Float.floatToIntBits(decoded));
538 }
539 }
540 }
541
542
543
544
545 @Test
546 public void testFloat64() {
547 Double[] vals =
548 { Double.MIN_VALUE, Double.MIN_VALUE + 1.0, 0.0, Double.MAX_VALUE / 2.0, Double.MAX_VALUE };
549
550
551
552
553
554 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
555 for (int i = 0; i < vals.length; i++) {
556
557 byte[] a = new byte[9 + 2];
558 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, 9);
559
560
561 assertEquals("Surprising return value.",
562 9, OrderedBytes.encodeFloat64(buf1, vals[i], ord));
563 assertEquals("Surprising serialized length.", 9, buf1.getPosition());
564 assertEquals("Buffer underflow.", 0, a[0]);
565 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
566
567
568 buf1.setPosition(0);
569 assertEquals("Surprising return value.", 9, OrderedBytes.skip(buf1));
570 assertEquals("Did not skip enough bytes.", 9, buf1.getPosition());
571
572
573 buf1.setPosition(0);
574 assertEquals("Deserialization failed.",
575 Double.doubleToLongBits(vals[i].doubleValue()),
576 Double.doubleToLongBits(OrderedBytes.decodeFloat64(buf1)));
577 assertEquals("Did not consume enough bytes.", 9, buf1.getPosition());
578 }
579 }
580
581
582
583
584 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
585 byte[][] encoded = new byte[vals.length][9];
586 PositionedByteRange pbr = new SimplePositionedByteRange();
587 for (int i = 0; i < vals.length; i++) {
588 OrderedBytes.encodeFloat64(pbr.set(encoded[i]), vals[i], ord);
589 }
590
591 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
592 Double[] sortedVals = Arrays.copyOf(vals, vals.length);
593 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
594 else Arrays.sort(sortedVals, Collections.reverseOrder());
595
596 for (int i = 0; i < sortedVals.length; i++) {
597 double decoded = OrderedBytes.decodeFloat64(pbr.set(encoded[i]));
598 assertEquals(
599 String.format(
600 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
601 sortedVals[i], decoded, ord),
602 Double.doubleToLongBits(sortedVals[i].doubleValue()),
603 Double.doubleToLongBits(decoded));
604 }
605 }
606 }
607
608
609
610
611 @Test
612 public void testString() {
613 String[] vals = { "foo", "baaaar", "bazz" };
614 int expectedLengths[] = { 5, 8, 6 };
615
616
617
618
619
620 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
621 for (int i = 0; i < vals.length; i++) {
622
623 byte[] a = new byte[expectedLengths[i] + 2];
624 PositionedByteRange buf1 = new SimplePositionedByteRange(a, 1, expectedLengths[i]);
625
626
627 assertEquals("Surprising return value.",
628 expectedLengths[i], OrderedBytes.encodeString(buf1, vals[i], ord));
629 assertEquals("Surprising serialized length.", expectedLengths[i], buf1.getPosition());
630 assertEquals("Buffer underflow.", 0, a[0]);
631 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
632
633
634 buf1.setPosition(0);
635 assertEquals("Surprising return value.", expectedLengths[i], OrderedBytes.skip(buf1));
636 assertEquals("Did not skip enough bytes.", expectedLengths[i], buf1.getPosition());
637
638
639 buf1.setPosition(0);
640 assertEquals("Deserialization failed.", vals[i], OrderedBytes.decodeString(buf1));
641 assertEquals("Did not consume enough bytes.", expectedLengths[i], buf1.getPosition());
642 }
643 }
644
645
646
647
648 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
649 byte[][] encoded = new byte[vals.length][];
650 PositionedByteRange pbr = new SimplePositionedByteRange();
651 for (int i = 0; i < vals.length; i++) {
652 encoded[i] = new byte[expectedLengths[i]];
653 OrderedBytes.encodeString(pbr.set(encoded[i]), vals[i], ord);
654 }
655
656 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
657 String[] sortedVals = Arrays.copyOf(vals, vals.length);
658 if (ord == Order.ASCENDING) Arrays.sort(sortedVals);
659 else Arrays.sort(sortedVals, Collections.reverseOrder());
660
661 for (int i = 0; i < sortedVals.length; i++) {
662 pbr.set(encoded[i]);
663 String decoded = OrderedBytes.decodeString(pbr);
664 assertEquals(
665 String.format(
666 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
667 sortedVals[i], decoded, ord),
668 sortedVals[i], decoded);
669 }
670 }
671 }
672
673 @Test(expected = IllegalArgumentException.class)
674 public void testStringNoNullChars() {
675 PositionedByteRange buff = new SimplePositionedByteRange(3);
676 OrderedBytes.encodeString(buff, "\u0000", Order.ASCENDING);
677 }
678
679
680
681
682
683 @Test
684 public void testBlobVarLencodedLength() {
685 int[][] values = {
686
687
688
689 { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 },
690 { 5, 7 }, { 6, 8 }, { 7, 9 }, { 8, 11 }
691 };
692
693 for (int[] pair : values) {
694 assertEquals(pair[1], OrderedBytes.blobVarEncodedLength(pair[0]));
695 assertEquals(pair[0], OrderedBytes.blobVarDecodedLength(pair[1]));
696 }
697 }
698
699
700
701
702 @Test
703 public void testBlobVar() {
704 byte[][] vals =
705 { "".getBytes(), "foo".getBytes(), "foobarbazbub".getBytes(),
706 { (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa,
707 (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa },
708 { (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55,
709 (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55 },
710 "1".getBytes(), "22".getBytes(), "333".getBytes(), "4444".getBytes(),
711 "55555".getBytes(), "666666".getBytes(), "7777777".getBytes(), "88888888".getBytes()
712 };
713
714
715
716
717
718 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
719 for (byte[] val : vals) {
720
721 int expectedLen = OrderedBytes.blobVarEncodedLength(val.length);
722 byte[] a = new byte[expectedLen + 2];
723 PositionedByteRange buf1 =
724 new SimplePositionedByteRange(a, 1, expectedLen);
725
726
727 assertEquals("Surprising return value.",
728 expectedLen, OrderedBytes.encodeBlobVar(buf1, val, ord));
729 assertEquals("Surprising serialized length.", expectedLen, buf1.getPosition());
730 assertEquals("Buffer underflow.", 0, a[0]);
731 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
732
733
734 buf1.setPosition(0);
735 assertEquals("Surprising return value.", expectedLen, OrderedBytes.skip(buf1));
736 assertEquals("Did not skip enough bytes.", expectedLen, buf1.getPosition());
737
738
739 buf1.setPosition(0);
740 assertArrayEquals("Deserialization failed.", val, OrderedBytes.decodeBlobVar(buf1));
741 assertEquals("Did not consume enough bytes.", expectedLen, buf1.getPosition());
742 }
743 }
744
745
746
747
748 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
749 byte[][] encoded = new byte[vals.length][];
750 PositionedByteRange pbr = new SimplePositionedByteRange();
751 for (int i = 0; i < vals.length; i++) {
752 encoded[i] = new byte[OrderedBytes.blobVarEncodedLength(vals[i].length)];
753 OrderedBytes.encodeBlobVar(pbr.set(encoded[i]), vals[i], ord);
754 }
755
756 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
757 byte[][] sortedVals = Arrays.copyOf(vals, vals.length);
758 if (ord == Order.ASCENDING) Arrays.sort(sortedVals, Bytes.BYTES_COMPARATOR);
759 else Arrays.sort(sortedVals, Collections.reverseOrder(Bytes.BYTES_COMPARATOR));
760
761 for (int i = 0; i < sortedVals.length; i++) {
762 pbr.set(encoded[i]);
763 byte[] decoded = OrderedBytes.decodeBlobVar(pbr);
764 assertArrayEquals(
765 String.format(
766 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
767 sortedVals[i], decoded, ord),
768 sortedVals[i], decoded);
769 }
770 }
771 }
772
773
774
775
776 @Test
777 public void testBlobCopy() {
778 byte[][] vals =
779 { "".getBytes(), "foo".getBytes(), "foobarbazbub".getBytes(),
780 { (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa,
781 (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa, (byte) 0xaa },
782 { (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55,
783 (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55 },
784 };
785
786
787
788
789
790 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
791 for (byte[] val : vals) {
792
793 int expectedLen = val.length + (Order.ASCENDING == ord ? 1 : 2);
794 byte[] a = new byte[expectedLen + 2];
795 PositionedByteRange buf1 =
796 new SimplePositionedByteRange(a, 1, expectedLen);
797
798
799 assertEquals("Surprising return value.",
800 expectedLen, OrderedBytes.encodeBlobCopy(buf1, val, ord));
801 assertEquals("Surprising serialized length.", expectedLen, buf1.getPosition());
802 assertEquals("Buffer underflow.", 0, a[0]);
803 assertEquals("Buffer overflow.", 0, a[a.length - 1]);
804
805
806 buf1.setPosition(0);
807 assertEquals("Surprising return value.", expectedLen, OrderedBytes.skip(buf1));
808 assertEquals("Did not skip enough bytes.", expectedLen, buf1.getPosition());
809
810
811 buf1.setPosition(0);
812 assertArrayEquals("Deserialization failed.", val, OrderedBytes.decodeBlobCopy(buf1));
813 assertEquals("Did not consume enough bytes.", expectedLen, buf1.getPosition());
814 }
815 }
816
817
818
819
820 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
821 byte[][] encoded = new byte[vals.length][];
822 PositionedByteRange pbr = new SimplePositionedByteRange();
823 for (int i = 0; i < vals.length; i++) {
824 encoded[i] = new byte[vals[i].length + (Order.ASCENDING == ord ? 1 : 2)];
825 OrderedBytes.encodeBlobCopy(pbr.set(encoded[i]), vals[i], ord);
826 }
827
828 Arrays.sort(encoded, Bytes.BYTES_COMPARATOR);
829 byte[][] sortedVals = Arrays.copyOf(vals, vals.length);
830 if (ord == Order.ASCENDING) Arrays.sort(sortedVals, Bytes.BYTES_COMPARATOR);
831 else Arrays.sort(sortedVals, Collections.reverseOrder(Bytes.BYTES_COMPARATOR));
832
833 for (int i = 0; i < sortedVals.length; i++) {
834 pbr.set(encoded[i]);
835 byte[] decoded = OrderedBytes.decodeBlobCopy(pbr);
836 assertArrayEquals(
837 String.format(
838 "Encoded representations do not preserve natural order: <%s>, <%s>, %s",
839 sortedVals[i], decoded, ord),
840 sortedVals[i], decoded);
841 }
842 }
843
844
845
846
847 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
848 byte[] a = new byte[3 + (Order.ASCENDING == ord ? 1 : 2) + 2];
849 PositionedByteRange buf =
850 new SimplePositionedByteRange(a, 1, 3 + (Order.ASCENDING == ord ? 1 : 2));
851 OrderedBytes.encodeBlobCopy(buf, "foobarbaz".getBytes(), 3, 3, ord);
852 buf.setPosition(0);
853 assertArrayEquals("bar".getBytes(), OrderedBytes.decodeBlobCopy(buf));
854 }
855 }
856
857
858
859
860 @Test(expected = IllegalArgumentException.class)
861 public void testBlobCopyNoZeroBytes() {
862 byte[] val = { 0x01, 0x02, 0x00, 0x03 };
863 byte[] ascExpected = { 0x36, 0x01, 0x02, 0x00, 0x03 };
864 PositionedByteRange buf = new SimplePositionedByteRange(val.length + 1);
865 OrderedBytes.encodeBlobCopy(buf, val, Order.ASCENDING);
866 assertArrayEquals(ascExpected, buf.getBytes());
867 buf.set(val.length + 2);
868 OrderedBytes.encodeBlobCopy(buf, val, Order.DESCENDING);
869 fail("test should never get here.");
870 }
871
872
873
874
875 @Test
876 public void testSkip() {
877 BigDecimal longMax = BigDecimal.valueOf(Long.MAX_VALUE);
878 double negInf = Double.NEGATIVE_INFINITY;
879 BigDecimal negLarge = longMax.multiply(longMax).negate();
880 BigDecimal negMed = new BigDecimal("-10.0");
881 BigDecimal negSmall = new BigDecimal("-0.0010");
882 long zero = 0l;
883 BigDecimal posSmall = negSmall.negate();
884 BigDecimal posMed = negMed.negate();
885 BigDecimal posLarge = negLarge.negate();
886 double posInf = Double.POSITIVE_INFINITY;
887 double nan = Double.NaN;
888 int int32 = 100;
889 long int64 = 100l;
890 float float32 = 100.0f;
891 double float64 = 100.0d;
892 String text = "hello world.";
893 byte[] blobVar = Bytes.toBytes("foo");
894 byte[] blobCopy = Bytes.toBytes("bar");
895
896 for (Order ord : new Order[] { Order.ASCENDING, Order.DESCENDING }) {
897 PositionedByteRange buff = new SimplePositionedByteRange(30);
898 int o;
899 o = OrderedBytes.encodeNull(buff, ord);
900 buff.setPosition(0);
901 assertEquals(o, OrderedBytes.skip(buff));
902
903 buff.setPosition(0);
904 o = OrderedBytes.encodeNumeric(buff, negInf, ord);
905 buff.setPosition(0);
906 assertEquals(o, OrderedBytes.skip(buff));
907
908 buff.setPosition(0);
909 o = OrderedBytes.encodeNumeric(buff, negLarge, ord);
910 buff.setPosition(0);
911 assertEquals(o, OrderedBytes.skip(buff));
912
913 buff.setPosition(0);
914 o = OrderedBytes.encodeNumeric(buff, negMed, ord);
915 buff.setPosition(0);
916 assertEquals(o, OrderedBytes.skip(buff));
917
918 buff.setPosition(0);
919 o = OrderedBytes.encodeNumeric(buff, negSmall, ord);
920 buff.setPosition(0);
921 assertEquals(o, OrderedBytes.skip(buff));
922
923 buff.setPosition(0);
924 o = OrderedBytes.encodeNumeric(buff, zero, ord);
925 buff.setPosition(0);
926 assertEquals(o, OrderedBytes.skip(buff));
927
928 buff.setPosition(0);
929 o = OrderedBytes.encodeNumeric(buff, posSmall, ord);
930 buff.setPosition(0);
931 assertEquals(o, OrderedBytes.skip(buff));
932
933 buff.setPosition(0);
934 o = OrderedBytes.encodeNumeric(buff, posMed, ord);
935 buff.setPosition(0);
936 assertEquals(o, OrderedBytes.skip(buff));
937
938 buff.setPosition(0);
939 o = OrderedBytes.encodeNumeric(buff, posLarge, ord);
940 buff.setPosition(0);
941 assertEquals(o, OrderedBytes.skip(buff));
942
943 buff.setPosition(0);
944 o = OrderedBytes.encodeNumeric(buff, posInf, ord);
945 buff.setPosition(0);
946 assertEquals(o, OrderedBytes.skip(buff));
947
948 buff.setPosition(0);
949 o = OrderedBytes.encodeNumeric(buff, nan, ord);
950 buff.setPosition(0);
951 assertEquals(o, OrderedBytes.skip(buff));
952
953 buff.setPosition(0);
954 o = OrderedBytes.encodeInt32(buff, int32, ord);
955 buff.setPosition(0);
956 assertEquals(o, OrderedBytes.skip(buff));
957
958 buff.setPosition(0);
959 o = OrderedBytes.encodeInt64(buff, int64, ord);
960 buff.setPosition(0);
961 assertEquals(o, OrderedBytes.skip(buff));
962
963 buff.setPosition(0);
964 o = OrderedBytes.encodeFloat32(buff, float32, ord);
965 buff.setPosition(0);
966 assertEquals(o, OrderedBytes.skip(buff));
967
968 buff.setPosition(0);
969 o = OrderedBytes.encodeFloat64(buff, float64, ord);
970 buff.setPosition(0);
971 assertEquals(o, OrderedBytes.skip(buff));
972
973 buff.setPosition(0);
974 o = OrderedBytes.encodeString(buff, text, ord);
975 buff.setPosition(0);
976 assertEquals(o, OrderedBytes.skip(buff));
977
978 buff.setPosition(0);
979 o = OrderedBytes.encodeBlobVar(buff, blobVar, ord);
980 buff.setPosition(0);
981 assertEquals(o, OrderedBytes.skip(buff));
982
983
984 buff.set(blobCopy.length + (Order.ASCENDING == ord ? 1 : 2));
985 o = OrderedBytes.encodeBlobCopy(buff, blobCopy, ord);
986 buff.setPosition(0);
987 assertEquals(o, OrderedBytes.skip(buff));
988 }
989 }
990 }