001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.util; 019 020import static org.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertFalse; 023import static org.junit.Assert.assertNotNull; 024import static org.junit.Assert.assertNotSame; 025import static org.junit.Assert.assertTrue; 026import static org.junit.Assert.fail; 027 028import java.io.ByteArrayInputStream; 029import java.io.ByteArrayOutputStream; 030import java.io.DataInputStream; 031import java.io.DataOutputStream; 032import java.io.IOException; 033import java.lang.reflect.Field; 034import java.lang.reflect.Modifier; 035import java.math.BigDecimal; 036import java.nio.ByteBuffer; 037import java.util.ArrayList; 038import java.util.Arrays; 039import java.util.List; 040import java.util.Random; 041import java.util.concurrent.ThreadLocalRandom; 042import org.apache.hadoop.hbase.HBaseClassTestRule; 043import org.apache.hadoop.hbase.testclassification.MediumTests; 044import org.apache.hadoop.hbase.testclassification.MiscTests; 045import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent; 046import org.apache.hadoop.io.WritableUtils; 047import org.junit.Assert; 048import org.junit.ClassRule; 049import org.junit.Test; 050import org.junit.experimental.categories.Category; 051 052@Category({ MiscTests.class, MediumTests.class }) 053public class TestBytes { 054 @ClassRule 055 public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestBytes.class); 056 057 private static void setUnsafe(boolean value) throws Exception { 058 Field field = Bytes.class.getDeclaredField("UNSAFE_UNALIGNED"); 059 field.setAccessible(true); 060 061 Field modifiersField = ReflectionUtils.getModifiersField(); 062 modifiersField.setAccessible(true); 063 int oldModifiers = field.getModifiers(); 064 modifiersField.setInt(field, oldModifiers & ~Modifier.FINAL); 065 try { 066 field.set(null, value); 067 } finally { 068 modifiersField.setInt(field, oldModifiers); 069 } 070 assertEquals(Bytes.UNSAFE_UNALIGNED, value); 071 } 072 073 @Test 074 public void testShort() throws Exception { 075 testShort(false); 076 } 077 078 @Test 079 public void testShortUnsafe() throws Exception { 080 testShort(true); 081 } 082 083 private static void testShort(boolean unsafe) throws Exception { 084 setUnsafe(unsafe); 085 try { 086 for (short n : Arrays.asList(Short.MIN_VALUE, (short) -100, (short) -1, (short) 0, (short) 1, 087 (short) 300, Short.MAX_VALUE)) { 088 byte[] bytes = Bytes.toBytes(n); 089 assertEquals(Bytes.toShort(bytes, 0, bytes.length), n); 090 } 091 } finally { 092 setUnsafe(HBasePlatformDependent.unaligned()); 093 } 094 } 095 096 @Test 097 public void testNullHashCode() { 098 byte[] b = null; 099 Exception ee = null; 100 try { 101 Bytes.hashCode(b); 102 } catch (Exception e) { 103 ee = e; 104 } 105 assertNotNull(ee); 106 } 107 108 @Test 109 public void testAdd() { 110 byte[] a = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 111 byte[] b = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 112 byte[] c = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }; 113 byte[] result1 = Bytes.add(a, b, c); 114 byte[] result2 = Bytes.add(new byte[][] { a, b, c }); 115 assertEquals(0, Bytes.compareTo(result1, result2)); 116 } 117 118 @Test 119 public void testSplit() { 120 byte[] lowest = Bytes.toBytes("AAA"); 121 byte[] middle = Bytes.toBytes("CCC"); 122 byte[] highest = Bytes.toBytes("EEE"); 123 byte[][] parts = Bytes.split(lowest, highest, 1); 124 for (byte[] bytes : parts) { 125 System.out.println(Bytes.toString(bytes)); 126 } 127 assertEquals(3, parts.length); 128 assertTrue(Bytes.equals(parts[1], middle)); 129 // Now divide into three parts. Change highest so split is even. 130 highest = Bytes.toBytes("DDD"); 131 parts = Bytes.split(lowest, highest, 2); 132 for (byte[] part : parts) { 133 System.out.println(Bytes.toString(part)); 134 } 135 assertEquals(4, parts.length); 136 // Assert that 3rd part is 'CCC'. 137 assertTrue(Bytes.equals(parts[2], middle)); 138 } 139 140 @Test 141 public void testSplit2() { 142 // More split tests. 143 byte[] lowest = Bytes.toBytes("http://A"); 144 byte[] highest = Bytes.toBytes("http://z"); 145 byte[] middle = Bytes.toBytes("http://]"); 146 byte[][] parts = Bytes.split(lowest, highest, 1); 147 for (byte[] part : parts) { 148 System.out.println(Bytes.toString(part)); 149 } 150 assertEquals(3, parts.length); 151 assertTrue(Bytes.equals(parts[1], middle)); 152 } 153 154 @Test 155 public void testSplit3() { 156 // Test invalid split cases 157 byte[] low = { 1, 1, 1 }; 158 byte[] high = { 1, 1, 3 }; 159 160 // If swapped, should throw IAE 161 try { 162 Bytes.split(high, low, 1); 163 fail("Should not be able to split if low > high"); 164 } catch (IllegalArgumentException iae) { 165 // Correct 166 } 167 168 // Single split should work 169 byte[][] parts = Bytes.split(low, high, 1); 170 for (int i = 0; i < parts.length; i++) { 171 System.out.println("" + i + " -> " + Bytes.toStringBinary(parts[i])); 172 } 173 assertEquals("Returned split should have 3 parts but has " + parts.length, 3, parts.length); 174 175 // If split more than once, use additional byte to split 176 parts = Bytes.split(low, high, 2); 177 assertNotNull("Split with an additional byte", parts); 178 assertEquals(parts.length, low.length + 1); 179 180 // Split 0 times should throw IAE 181 try { 182 Bytes.split(low, high, 0); 183 fail("Should not be able to split 0 times"); 184 } catch (IllegalArgumentException iae) { 185 // Correct 186 } 187 } 188 189 @Test 190 public void testToInt() { 191 int[] ints = { -1, 123, Integer.MIN_VALUE, Integer.MAX_VALUE }; 192 for (int anInt : ints) { 193 byte[] b = Bytes.toBytes(anInt); 194 assertEquals(anInt, Bytes.toInt(b)); 195 byte[] b2 = bytesWithOffset(b); 196 assertEquals(anInt, Bytes.toInt(b2, 1)); 197 assertEquals(anInt, Bytes.toInt(b2, 1, Bytes.SIZEOF_INT)); 198 } 199 } 200 201 @Test 202 public void testToLong() { 203 long[] longs = { -1L, 123L, Long.MIN_VALUE, Long.MAX_VALUE }; 204 for (long aLong : longs) { 205 byte[] b = Bytes.toBytes(aLong); 206 assertEquals(aLong, Bytes.toLong(b)); 207 byte[] b2 = bytesWithOffset(b); 208 assertEquals(aLong, Bytes.toLong(b2, 1)); 209 assertEquals(aLong, Bytes.toLong(b2, 1, Bytes.SIZEOF_LONG)); 210 } 211 } 212 213 @Test 214 public void testToFloat() { 215 float[] floats = { -1f, 123.123f, Float.MAX_VALUE }; 216 for (float aFloat : floats) { 217 byte[] b = Bytes.toBytes(aFloat); 218 assertEquals(aFloat, Bytes.toFloat(b), 0.0f); 219 byte[] b2 = bytesWithOffset(b); 220 assertEquals(aFloat, Bytes.toFloat(b2, 1), 0.0f); 221 } 222 } 223 224 @Test 225 public void testToDouble() { 226 double[] doubles = { Double.MIN_VALUE, Double.MAX_VALUE }; 227 for (double aDouble : doubles) { 228 byte[] b = Bytes.toBytes(aDouble); 229 assertEquals(aDouble, Bytes.toDouble(b), 0.0); 230 byte[] b2 = bytesWithOffset(b); 231 assertEquals(aDouble, Bytes.toDouble(b2, 1), 0.0); 232 } 233 } 234 235 @Test 236 public void testToBigDecimal() { 237 BigDecimal[] decimals = 238 { new BigDecimal("-1"), new BigDecimal("123.123"), new BigDecimal("123123123123") }; 239 for (BigDecimal decimal : decimals) { 240 byte[] b = Bytes.toBytes(decimal); 241 assertEquals(decimal, Bytes.toBigDecimal(b)); 242 byte[] b2 = bytesWithOffset(b); 243 assertEquals(decimal, Bytes.toBigDecimal(b2, 1, b.length)); 244 } 245 } 246 247 private byte[] bytesWithOffset(byte[] src) { 248 // add one byte in front to test offset 249 byte[] result = new byte[src.length + 1]; 250 result[0] = (byte) 0xAA; 251 System.arraycopy(src, 0, result, 1, src.length); 252 return result; 253 } 254 255 @Test 256 public void testToBytesForByteBuffer() { 257 byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 258 ByteBuffer target = ByteBuffer.wrap(array); 259 target.position(2); 260 target.limit(7); 261 262 byte[] actual = Bytes.toBytes(target); 263 byte[] expected = { 0, 1, 2, 3, 4, 5, 6 }; 264 assertArrayEquals(expected, actual); 265 assertEquals(2, target.position()); 266 assertEquals(7, target.limit()); 267 268 ByteBuffer target2 = target.slice(); 269 assertEquals(0, target2.position()); 270 assertEquals(5, target2.limit()); 271 272 byte[] actual2 = Bytes.toBytes(target2); 273 byte[] expected2 = { 2, 3, 4, 5, 6 }; 274 assertArrayEquals(expected2, actual2); 275 assertEquals(0, target2.position()); 276 assertEquals(5, target2.limit()); 277 } 278 279 @Test 280 public void testGetBytesForByteBuffer() { 281 byte[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 282 ByteBuffer target = ByteBuffer.wrap(array); 283 target.position(2); 284 target.limit(7); 285 286 byte[] actual = Bytes.getBytes(target); 287 byte[] expected = { 2, 3, 4, 5, 6 }; 288 assertArrayEquals(expected, actual); 289 assertEquals(2, target.position()); 290 assertEquals(7, target.limit()); 291 } 292 293 @Test 294 public void testReadAsVLong() throws Exception { 295 long[] longs = { -1L, 123L, Long.MIN_VALUE, Long.MAX_VALUE }; 296 for (long aLong : longs) { 297 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 298 DataOutputStream output = new DataOutputStream(baos); 299 WritableUtils.writeVLong(output, aLong); 300 byte[] long_bytes_no_offset = baos.toByteArray(); 301 assertEquals(aLong, Bytes.readAsVLong(long_bytes_no_offset, 0)); 302 byte[] long_bytes_with_offset = bytesWithOffset(long_bytes_no_offset); 303 assertEquals(aLong, Bytes.readAsVLong(long_bytes_with_offset, 1)); 304 } 305 } 306 307 @Test 308 public void testToStringBinaryForBytes() { 309 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 }; 310 String actual = Bytes.toStringBinary(array); 311 String expected = "09azAZ@\\x01"; 312 assertEquals(expected, actual); 313 314 String actual2 = Bytes.toStringBinary(array, 2, 3); 315 String expected2 = "azA"; 316 assertEquals(expected2, actual2); 317 } 318 319 @Test 320 public void testToStringBinaryForArrayBasedByteBuffer() { 321 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 }; 322 ByteBuffer target = ByteBuffer.wrap(array); 323 String actual = Bytes.toStringBinary(target); 324 String expected = "09azAZ@\\x01"; 325 assertEquals(expected, actual); 326 } 327 328 @Test 329 public void testToStringBinaryForReadOnlyByteBuffer() { 330 byte[] array = { '0', '9', 'a', 'z', 'A', 'Z', '@', 1 }; 331 ByteBuffer target = ByteBuffer.wrap(array).asReadOnlyBuffer(); 332 String actual = Bytes.toStringBinary(target); 333 String expected = "09azAZ@\\x01"; 334 assertEquals(expected, actual); 335 } 336 337 @Test 338 public void testBinarySearch() { 339 byte[][] arr = { { 1 }, { 3 }, { 5 }, { 7 }, { 9 }, { 11 }, { 13 }, { 15 }, }; 340 byte[] key1 = { 3, 1 }; 341 byte[] key2 = { 4, 9 }; 342 byte[] key2_2 = { 4 }; 343 byte[] key3 = { 5, 11 }; 344 byte[] key4 = { 0 }; 345 byte[] key5 = { 2 }; 346 347 assertEquals(1, Bytes.binarySearch(arr, key1, 0, 1)); 348 assertEquals(0, Bytes.binarySearch(arr, key1, 1, 1)); 349 assertEquals(-(2 + 1), Arrays.binarySearch(arr, key2_2, Bytes.BYTES_COMPARATOR)); 350 assertEquals(-(2 + 1), Bytes.binarySearch(arr, key2, 0, 1)); 351 assertEquals(4, Bytes.binarySearch(arr, key2, 1, 1)); 352 assertEquals(2, Bytes.binarySearch(arr, key3, 0, 1)); 353 assertEquals(5, Bytes.binarySearch(arr, key3, 1, 1)); 354 assertEquals(-1, Bytes.binarySearch(arr, key4, 0, 1)); 355 assertEquals(-2, Bytes.binarySearch(arr, key5, 0, 1)); 356 357 // Search for values to the left and to the right of each item in the array. 358 for (int i = 0; i < arr.length; ++i) { 359 assertEquals(-(i + 1), Bytes.binarySearch(arr, new byte[] { (byte) (arr[i][0] - 1) }, 0, 1)); 360 assertEquals(-(i + 2), Bytes.binarySearch(arr, new byte[] { (byte) (arr[i][0] + 1) }, 0, 1)); 361 } 362 } 363 364 @Test 365 public void testToStringBytesBinaryReversible() { 366 byte[] randomBytes = new byte[1000]; 367 for (int i = 0; i < 1000; i++) { 368 Bytes.random(randomBytes); 369 verifyReversibleForBytes(randomBytes); 370 } 371 // some specific cases 372 verifyReversibleForBytes(new byte[] {}); 373 verifyReversibleForBytes(new byte[] { '\\', 'x', 'A', 'D' }); 374 verifyReversibleForBytes(new byte[] { '\\', 'x', 'A', 'D', '\\' }); 375 } 376 377 private void verifyReversibleForBytes(byte[] originalBytes) { 378 String convertedString = Bytes.toStringBinary(originalBytes); 379 byte[] convertedBytes = Bytes.toBytesBinary(convertedString); 380 if (Bytes.compareTo(originalBytes, convertedBytes) != 0) { 381 fail("Not reversible for\nbyte[]: " + Arrays.toString(originalBytes) + ",\nStringBinary: " 382 + convertedString); 383 } 384 } 385 386 @Test 387 public void testStartsWith() { 388 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("h"))); 389 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes(""))); 390 assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("hello"))); 391 assertFalse(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("helloworld"))); 392 assertFalse(Bytes.startsWith(Bytes.toBytes(""), Bytes.toBytes("hello"))); 393 } 394 395 @Test 396 public void testIncrementBytes() { 397 assertTrue(checkTestIncrementBytes(10, 1)); 398 assertTrue(checkTestIncrementBytes(12, 123435445)); 399 assertTrue(checkTestIncrementBytes(124634654, 1)); 400 assertTrue(checkTestIncrementBytes(10005460, 5005645)); 401 assertTrue(checkTestIncrementBytes(1, -1)); 402 assertTrue(checkTestIncrementBytes(10, -1)); 403 assertTrue(checkTestIncrementBytes(10, -5)); 404 assertTrue(checkTestIncrementBytes(1005435000, -5)); 405 assertTrue(checkTestIncrementBytes(10, -43657655)); 406 assertTrue(checkTestIncrementBytes(-1, 1)); 407 assertTrue(checkTestIncrementBytes(-26, 5034520)); 408 assertTrue(checkTestIncrementBytes(-10657200, 5)); 409 assertTrue(checkTestIncrementBytes(-12343250, 45376475)); 410 assertTrue(checkTestIncrementBytes(-10, -5)); 411 assertTrue(checkTestIncrementBytes(-12343250, -5)); 412 assertTrue(checkTestIncrementBytes(-12, -34565445)); 413 assertTrue(checkTestIncrementBytes(-1546543452, -34565445)); 414 } 415 416 private static boolean checkTestIncrementBytes(long val, long amount) { 417 byte[] value = Bytes.toBytes(val); 418 byte[] testValue = { -1, -1, -1, -1, -1, -1, -1, -1 }; 419 if (value[0] > 0) { 420 testValue = new byte[Bytes.SIZEOF_LONG]; 421 } 422 System.arraycopy(value, 0, testValue, testValue.length - value.length, value.length); 423 424 long incrementResult = Bytes.toLong(Bytes.incrementBytes(value, amount)); 425 426 return (Bytes.toLong(testValue) + amount) == incrementResult; 427 } 428 429 @Test 430 public void testFixedSizeString() throws IOException { 431 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 432 DataOutputStream dos = new DataOutputStream(baos); 433 Bytes.writeStringFixedSize(dos, "Hello", 5); 434 Bytes.writeStringFixedSize(dos, "World", 18); 435 Bytes.writeStringFixedSize(dos, "", 9); 436 437 try { 438 // Use a long dash which is three bytes in UTF-8. If encoding happens 439 // using ISO-8859-1, this will fail. 440 Bytes.writeStringFixedSize(dos, "Too\u2013Long", 9); 441 fail("Exception expected"); 442 } catch (IOException ex) { 443 assertEquals( 444 "Trying to write 10 bytes (Too\\xE2\\x80\\x93Long) into a field of " + "length 9", 445 ex.getMessage()); 446 } 447 448 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 449 DataInputStream dis = new DataInputStream(bais); 450 assertEquals("Hello", Bytes.readStringFixedSize(dis, 5)); 451 assertEquals("World", Bytes.readStringFixedSize(dis, 18)); 452 assertEquals("", Bytes.readStringFixedSize(dis, 9)); 453 } 454 455 @Test 456 public void testCopy() { 457 byte[] bytes = Bytes.toBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 458 byte[] copy = Bytes.copy(bytes); 459 assertNotSame(bytes, copy); 460 assertTrue(Bytes.equals(bytes, copy)); 461 } 462 463 @Test 464 public void testToBytesBinaryTrailingBackslashes() { 465 try { 466 Bytes.toBytesBinary("abc\\x00\\x01\\"); 467 } catch (StringIndexOutOfBoundsException ex) { 468 fail("Illegal string access: " + ex.getMessage()); 469 } 470 } 471 472 @Test 473 public void testToStringBinary_toBytesBinary_Reversable() { 474 String bytes = Bytes.toStringBinary(Bytes.toBytes(2.17)); 475 assertEquals(2.17, Bytes.toDouble(Bytes.toBytesBinary(bytes)), 0); 476 } 477 478 @Test 479 public void testUnsignedBinarySearch() { 480 byte[] bytes = new byte[] { 0, 5, 123, 127, -128, -100, -1 }; 481 Assert.assertEquals(1, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) 5)); 482 Assert.assertEquals(3, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) 127)); 483 Assert.assertEquals(4, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -128)); 484 Assert.assertEquals(5, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -100)); 485 Assert.assertEquals(6, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -1)); 486 Assert.assertEquals(-1 - 1, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) 2)); 487 Assert.assertEquals(-6 - 1, Bytes.unsignedBinarySearch(bytes, 0, bytes.length, (byte) -5)); 488 } 489 490 @Test 491 public void testUnsignedIncrement() { 492 byte[] a = Bytes.toBytes(0); 493 int a2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(a), 0); 494 Assert.assertEquals(1, a2); 495 496 byte[] b = Bytes.toBytes(-1); 497 byte[] actual = Bytes.unsignedCopyAndIncrement(b); 498 Assert.assertNotSame(b, actual); 499 byte[] expected = new byte[] { 1, 0, 0, 0, 0 }; 500 assertArrayEquals(expected, actual); 501 502 byte[] c = Bytes.toBytes(255);// should wrap to the next significant byte 503 int c2 = Bytes.toInt(Bytes.unsignedCopyAndIncrement(c), 0); 504 Assert.assertEquals(256, c2); 505 } 506 507 @Test 508 public void testIndexOf() { 509 byte[] array = Bytes.toBytes("hello"); 510 assertEquals(1, Bytes.indexOf(array, (byte) 'e')); 511 assertEquals(4, Bytes.indexOf(array, (byte) 'o')); 512 assertEquals(-1, Bytes.indexOf(array, (byte) 'a')); 513 assertEquals(0, Bytes.indexOf(array, Bytes.toBytes("hel"))); 514 assertEquals(2, Bytes.indexOf(array, Bytes.toBytes("ll"))); 515 assertEquals(-1, Bytes.indexOf(array, Bytes.toBytes("hll"))); 516 } 517 518 @Test 519 public void testContains() { 520 byte[] array = Bytes.toBytes("hello world"); 521 assertTrue(Bytes.contains(array, (byte) 'e')); 522 assertTrue(Bytes.contains(array, (byte) 'd')); 523 assertFalse(Bytes.contains(array, (byte) 'a')); 524 assertTrue(Bytes.contains(array, Bytes.toBytes("world"))); 525 assertTrue(Bytes.contains(array, Bytes.toBytes("ello"))); 526 assertFalse(Bytes.contains(array, Bytes.toBytes("owo"))); 527 } 528 529 @Test 530 public void testZero() { 531 byte[] array = Bytes.toBytes("hello"); 532 Bytes.zero(array); 533 for (byte b : array) { 534 assertEquals(0, b); 535 } 536 array = Bytes.toBytes("hello world"); 537 Bytes.zero(array, 2, 7); 538 assertFalse(array[0] == 0); 539 assertFalse(array[1] == 0); 540 for (int i = 2; i < 9; i++) { 541 assertEquals(0, array[i]); 542 } 543 for (int i = 9; i < array.length; i++) { 544 assertFalse(array[i] == 0); 545 } 546 } 547 548 @Test 549 public void testPutBuffer() { 550 byte[] b = new byte[100]; 551 for (byte i = 0; i < 100; i++) { 552 Bytes.putByteBuffer(b, i, ByteBuffer.wrap(new byte[] { i })); 553 } 554 for (byte i = 0; i < 100; i++) { 555 Assert.assertEquals(i, b[i]); 556 } 557 } 558 559 @Test 560 public void testToFromHex() { 561 List<String> testStrings = new ArrayList<>(8); 562 testStrings.addAll(Arrays.asList("", "00", "A0", "ff", "FFffFFFFFFFFFF", "12", 563 "0123456789abcdef", "283462839463924623984692834692346ABCDFEDDCA0")); 564 for (String testString : testStrings) { 565 byte[] byteData = Bytes.fromHex(testString); 566 Assert.assertEquals(testString.length() / 2, byteData.length); 567 String result = Bytes.toHex(byteData); 568 Assert.assertTrue(testString.equalsIgnoreCase(result)); 569 } 570 571 List<byte[]> testByteData = new ArrayList<>(5); 572 testByteData.addAll(Arrays.asList(new byte[0], new byte[1], new byte[10], 573 new byte[] { 1, 2, 3, 4, 5 }, new byte[] { (byte) 0xFF })); 574 Random rand = ThreadLocalRandom.current(); 575 for (int i = 0; i < 20; i++) { 576 byte[] bytes = new byte[rand.nextInt(100)]; 577 Bytes.random(bytes); 578 testByteData.add(bytes); 579 } 580 581 for (byte[] testData : testByteData) { 582 String hexString = Bytes.toHex(testData); 583 Assert.assertEquals(testData.length * 2, hexString.length()); 584 byte[] result = Bytes.fromHex(hexString); 585 assertArrayEquals(testData, result); 586 } 587 } 588 589 @Test 590 public void testFindCommonPrefix() throws Exception { 591 testFindCommonPrefix(false); 592 } 593 594 @Test 595 public void testFindCommonPrefixUnsafe() throws Exception { 596 testFindCommonPrefix(true); 597 } 598 599 private static void testFindCommonPrefix(boolean unsafe) throws Exception { 600 setUnsafe(unsafe); 601 try { 602 // tests for common prefixes less than 8 bytes in length (i.e. using non-vectorized path) 603 byte[] hello = Bytes.toBytes("hello"); 604 byte[] helloWorld = Bytes.toBytes("helloworld"); 605 606 assertEquals(5, 607 Bytes.findCommonPrefix(hello, helloWorld, hello.length, helloWorld.length, 0, 0)); 608 assertEquals(5, Bytes.findCommonPrefix(hello, hello, hello.length, hello.length, 0, 0)); 609 assertEquals(3, 610 Bytes.findCommonPrefix(hello, hello, hello.length - 2, hello.length - 2, 2, 2)); 611 assertEquals(0, Bytes.findCommonPrefix(hello, hello, 0, 0, 0, 0)); 612 613 // tests for common prefixes greater than 8 bytes in length which may use the vectorized path 614 byte[] hellohello = Bytes.toBytes("hellohello"); 615 byte[] hellohellohi = Bytes.toBytes("hellohellohi"); 616 617 assertEquals(10, Bytes.findCommonPrefix(hellohello, hellohellohi, hellohello.length, 618 hellohellohi.length, 0, 0)); 619 assertEquals(10, Bytes.findCommonPrefix(hellohellohi, hellohello, hellohellohi.length, 620 hellohello.length, 0, 0)); 621 assertEquals(10, 622 Bytes.findCommonPrefix(hellohello, hellohello, hellohello.length, hellohello.length, 0, 0)); 623 624 hellohello[2] = 0; 625 assertEquals(2, Bytes.findCommonPrefix(hellohello, hellohellohi, hellohello.length, 626 hellohellohi.length, 0, 0)); 627 } finally { 628 setUnsafe(HBasePlatformDependent.unaligned()); 629 } 630 } 631}