1 /* 2 * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @compile/module=java.base java/util/SortingHelper.java 27 * @bug 6880672 6896573 6899694 6976036 7013585 7018258 8003981 8226297 28 * @build Sorting 29 * @run main Sorting -shortrun 30 * @summary Exercise Arrays.sort, Arrays.parallelSort 31 * 32 * @author Vladimir Yaroslavskiy 33 * @author Jon Bentley 34 * @author Josh Bloch 35 */ 36 37 package test.java.util.Arrays; 38 39 import android.platform.test.annotations.LargeTest; 40 41 import java.io.PrintStream; 42 import java.util.Comparator; 43 import java.util.Random; 44 45 @LargeTest 46 @SuppressWarnings("IdentityBinaryExpression") 47 public class Sorting { 48 49 private static final PrintStream out = System.out; 50 private static final PrintStream err = System.err; 51 52 // Array lengths used in a long run (default) 53 private static final int[] LONG_RUN_LENGTHS = { 54 1, 3, 8, 21, 55, 100, 1_000, 10_000, 100_000 }; 55 56 // Array lengths used in a short run 57 private static final int[] SHORT_RUN_LENGTHS = { 58 1, 8, 55, 100, 10_000 }; 59 60 // Random initial values used in a long run (default) 61 private static final TestRandom[] LONG_RUN_RANDOMS = { 62 TestRandom.BABA, TestRandom.DEDA, TestRandom.C0FFEE }; 63 64 // Random initial values used in a short run 65 private static final TestRandom[] SHORT_RUN_RANDOMS = { 66 TestRandom.C0FFEE }; 67 68 // Constants used in subarray sorting 69 private static final int A380 = 0xA380; 70 private static final int B747 = 0xB747; 71 72 @LargeTest main(String[] args)73 public static void main(String[] args) { 74 long start = System.currentTimeMillis(); 75 // Android-changed: coverage run with this flag set to true takes too 76 // much time. Locally it was killed after 45 minutes. 77 // boolean shortRun = args.length > 0 && args[0].equals("-shortrun"); 78 boolean shortRun = true; 79 80 int[] lengths = shortRun ? SHORT_RUN_LENGTHS : LONG_RUN_LENGTHS; 81 TestRandom[] randoms = shortRun ? SHORT_RUN_RANDOMS : LONG_RUN_RANDOMS; 82 83 new InnerState(SortingHelper.DUAL_PIVOT_QUICKSORT, randoms, lengths).testCore(); 84 new InnerState(SortingHelper.PARALLEL_SORT, randoms, lengths).testCore(); 85 new InnerState(SortingHelper.HEAP_SORT, randoms, lengths).testBasic(); 86 new InnerState(SortingHelper.ARRAYS_SORT, randoms, lengths).testAll(); 87 new InnerState(SortingHelper.ARRAYS_PARALLEL_SORT, randoms, lengths).testAll(); 88 89 long end = System.currentTimeMillis(); 90 out.format("PASSED in %d sec.\n", (end - start) / 1000); 91 } 92 93 // Android-changed: runner can't run test with non-default contructor. 94 private static class InnerState { 95 private final SortingHelper sortingHelper; 96 private final TestRandom[] randoms; 97 private final int[] lengths; 98 private Object[] gold; 99 private Object[] test; 100 InnerState(SortingHelper sortingHelper, TestRandom[] randoms, int[] lengths)101 public InnerState(SortingHelper sortingHelper, TestRandom[] randoms, int[] lengths) { 102 this.sortingHelper = sortingHelper; 103 this.randoms = randoms; 104 this.lengths = lengths; 105 } 106 testBasic()107 private void testBasic() { 108 testEmptyArray(); 109 110 for (int length : lengths) { 111 createData(length); 112 testBasic(length); 113 } 114 } 115 testBasic(int length)116 private void testBasic(int length) { 117 for (TestRandom random : randoms) { 118 testWithInsertionSort(length, random); 119 testWithCheckSum(length, random); 120 testWithScrambling(length, random); 121 } 122 } 123 testCore()124 private void testCore() { 125 for (int length : lengths) { 126 createData(length); 127 testCore(length); 128 } 129 } 130 testCore(int length)131 private void testCore(int length) { 132 testBasic(length); 133 134 for (TestRandom random : randoms) { 135 testMergingSort(length, random); 136 testSubArray(length, random); 137 testNegativeZero(length, random); 138 testFloatingPointSorting(length, random); 139 } 140 } 141 testAll()142 private void testAll() { 143 for (int length : lengths) { 144 createData(length); 145 testAll(length); 146 } 147 } 148 testAll(int length)149 private void testAll(int length) { 150 testCore(length); 151 152 for (TestRandom random : randoms) { 153 testRange(length, random); 154 testStability(length, random); 155 } 156 } 157 testEmptyArray()158 private void testEmptyArray() { 159 testEmptyAndNullIntArray(); 160 testEmptyAndNullLongArray(); 161 testEmptyAndNullByteArray(); 162 testEmptyAndNullCharArray(); 163 testEmptyAndNullShortArray(); 164 testEmptyAndNullFloatArray(); 165 testEmptyAndNullDoubleArray(); 166 } 167 testStability(int length, TestRandom random)168 private void testStability(int length, TestRandom random) { 169 printTestName("Test stability", random, length); 170 171 Pair[] a = build(length, random); 172 sortingHelper.sort(a); 173 checkSorted(a); 174 checkStable(a); 175 176 a = build(length, random); 177 sortingHelper.sort(a, pairComparator); 178 checkSorted(a); 179 checkStable(a); 180 181 out.println(); 182 } 183 testEmptyAndNullIntArray()184 private void testEmptyAndNullIntArray() { 185 sortingHelper.sort(new int[]{}); 186 sortingHelper.sort(new int[]{}, 0, 0); 187 188 try { 189 sortingHelper.sort(null); 190 } catch (NullPointerException expected) { 191 try { 192 sortingHelper.sort(null, 0, 0); 193 } catch (NullPointerException expected2) { 194 return; 195 } 196 fail(sortingHelper + "(int[],fromIndex,toIndex) shouldn't " + 197 "catch null array"); 198 } 199 fail(sortingHelper + "(int[]) shouldn't catch null array"); 200 } 201 testEmptyAndNullLongArray()202 private void testEmptyAndNullLongArray() { 203 sortingHelper.sort(new long[]{}); 204 sortingHelper.sort(new long[]{}, 0, 0); 205 206 try { 207 sortingHelper.sort(null); 208 } catch (NullPointerException expected) { 209 try { 210 sortingHelper.sort(null, 0, 0); 211 } catch (NullPointerException expected2) { 212 return; 213 } 214 fail(sortingHelper + "(long[],fromIndex,toIndex) shouldn't " + 215 "catch null array"); 216 } 217 fail(sortingHelper + "(long[]) shouldn't catch null array"); 218 } 219 testEmptyAndNullByteArray()220 private void testEmptyAndNullByteArray() { 221 sortingHelper.sort(new byte[]{}); 222 sortingHelper.sort(new byte[]{}, 0, 0); 223 224 try { 225 sortingHelper.sort(null); 226 } catch (NullPointerException expected) { 227 try { 228 sortingHelper.sort(null, 0, 0); 229 } catch (NullPointerException expected2) { 230 return; 231 } 232 fail(sortingHelper + "(byte[],fromIndex,toIndex) shouldn't " + 233 "catch null array"); 234 } 235 fail(sortingHelper + "(byte[]) shouldn't catch null array"); 236 } 237 testEmptyAndNullCharArray()238 private void testEmptyAndNullCharArray() { 239 sortingHelper.sort(new char[]{}); 240 sortingHelper.sort(new char[]{}, 0, 0); 241 242 try { 243 sortingHelper.sort(null); 244 } catch (NullPointerException expected) { 245 try { 246 sortingHelper.sort(null, 0, 0); 247 } catch (NullPointerException expected2) { 248 return; 249 } 250 fail(sortingHelper + "(char[],fromIndex,toIndex) shouldn't " + 251 "catch null array"); 252 } 253 fail(sortingHelper + "(char[]) shouldn't catch null array"); 254 } 255 testEmptyAndNullShortArray()256 private void testEmptyAndNullShortArray() { 257 sortingHelper.sort(new short[]{}); 258 sortingHelper.sort(new short[]{}, 0, 0); 259 260 try { 261 sortingHelper.sort(null); 262 } catch (NullPointerException expected) { 263 try { 264 sortingHelper.sort(null, 0, 0); 265 } catch (NullPointerException expected2) { 266 return; 267 } 268 fail(sortingHelper + "(short[],fromIndex,toIndex) shouldn't " + 269 "catch null array"); 270 } 271 fail(sortingHelper + "(short[]) shouldn't catch null array"); 272 } 273 testEmptyAndNullFloatArray()274 private void testEmptyAndNullFloatArray() { 275 sortingHelper.sort(new float[]{}); 276 sortingHelper.sort(new float[]{}, 0, 0); 277 278 try { 279 sortingHelper.sort(null); 280 } catch (NullPointerException expected) { 281 try { 282 sortingHelper.sort(null, 0, 0); 283 } catch (NullPointerException expected2) { 284 return; 285 } 286 fail(sortingHelper + "(float[],fromIndex,toIndex) shouldn't " + 287 "catch null array"); 288 } 289 fail(sortingHelper + "(float[]) shouldn't catch null array"); 290 } 291 testEmptyAndNullDoubleArray()292 private void testEmptyAndNullDoubleArray() { 293 sortingHelper.sort(new double[]{}); 294 sortingHelper.sort(new double[]{}, 0, 0); 295 296 try { 297 sortingHelper.sort(null); 298 } catch (NullPointerException expected) { 299 try { 300 sortingHelper.sort(null, 0, 0); 301 } catch (NullPointerException expected2) { 302 return; 303 } 304 fail(sortingHelper + "(double[],fromIndex,toIndex) shouldn't " + 305 "catch null array"); 306 } 307 fail(sortingHelper + "(double[]) shouldn't catch null array"); 308 } 309 testSubArray(int length, TestRandom random)310 private void testSubArray(int length, TestRandom random) { 311 if (length < 4) { 312 return; 313 } 314 for (int m = 1; m < length / 2; m <<= 1) { 315 int fromIndex = m; 316 int toIndex = length - m; 317 318 prepareSubArray((int[]) gold[0], fromIndex, toIndex); 319 convertData(length); 320 321 for (int i = 0; i < test.length; i++) { 322 printTestName("Test subarray", random, length, 323 ", m = " + m + ", " + getType(i)); 324 sortingHelper.sort(test[i], fromIndex, toIndex); 325 checkSubArray(test[i], fromIndex, toIndex); 326 } 327 } 328 out.println(); 329 } 330 testRange(int length, TestRandom random)331 private void testRange(int length, TestRandom random) { 332 if (length < 2) { 333 return; 334 } 335 for (int m = 1; m < length; m <<= 1) { 336 for (int i = 1; i <= length; i++) { 337 ((int[]) gold[0])[i - 1] = i % m + m % i; 338 } 339 convertData(length); 340 341 for (int i = 0; i < test.length; i++) { 342 printTestName("Test range check", random, length, 343 ", m = " + m + ", " + getType(i)); 344 checkRange(test[i], m); 345 } 346 } 347 out.println(); 348 } 349 checkSorted(Pair[] a)350 private void checkSorted(Pair[] a) { 351 for (int i = 0; i < a.length - 1; i++) { 352 if (a[i].getKey() > a[i + 1].getKey()) { 353 fail("Array is not sorted at " + i + "-th position: " + 354 a[i].getKey() + " and " + a[i + 1].getKey()); 355 } 356 } 357 } 358 checkStable(Pair[] a)359 private void checkStable(Pair[] a) { 360 for (int i = 0; i < a.length / 4; ) { 361 int key1 = a[i].getKey(); 362 int value1 = a[i++].getValue(); 363 int key2 = a[i].getKey(); 364 int value2 = a[i++].getValue(); 365 int key3 = a[i].getKey(); 366 int value3 = a[i++].getValue(); 367 int key4 = a[i].getKey(); 368 int value4 = a[i++].getValue(); 369 370 if (!(key1 == key2 && key2 == key3 && key3 == key4)) { 371 fail("Keys are different " + key1 + ", " + key2 + ", " + 372 key3 + ", " + key4 + " at position " + i); 373 } 374 if (!(value1 < value2 && value2 < value3 && value3 < value4)) { 375 fail("Sorting is not stable at position " + i + 376 ". Second values have been changed: " + value1 + ", " + 377 value2 + ", " + value3 + ", " + value4); 378 } 379 } 380 } 381 build(int length, Random random)382 private Pair[] build(int length, Random random) { 383 Pair[] a = new Pair[length * 4]; 384 385 for (int i = 0; i < a.length; ) { 386 int key = random.nextInt(); 387 a[i++] = new Pair(key, 1); 388 a[i++] = new Pair(key, 2); 389 a[i++] = new Pair(key, 3); 390 a[i++] = new Pair(key, 4); 391 } 392 return a; 393 } 394 testWithInsertionSort(int length, TestRandom random)395 private void testWithInsertionSort(int length, TestRandom random) { 396 if (length > 1000) { 397 return; 398 } 399 for (int m = 1; m <= length; m <<= 1) { 400 for (UnsortedBuilder builder : UnsortedBuilder.values()) { 401 builder.build((int[]) gold[0], m, random); 402 convertData(length); 403 404 for (int i = 0; i < test.length; i++) { 405 printTestName("Test with insertion sort", random, length, 406 ", m = " + m + ", " + getType(i) + " " + builder); 407 sortingHelper.sort(test[i]); 408 sortByInsertionSort(gold[i]); 409 compare(test[i], gold[i]); 410 } 411 } 412 } 413 out.println(); 414 } 415 testMergingSort(int length, TestRandom random)416 private void testMergingSort(int length, TestRandom random) { 417 if (length < (4 << 10)) { // DualPivotQuicksort.MIN_TRY_MERGE_SIZE 418 return; 419 } 420 final int PERIOD = 50; 421 422 for (int m = PERIOD - 2; m <= PERIOD + 2; m++) { 423 for (MergingBuilder builder : MergingBuilder.values()) { 424 builder.build((int[]) gold[0], m); 425 convertData(length); 426 427 for (int i = 0; i < test.length; i++) { 428 printTestName("Test merging sort", random, length, 429 ", m = " + m + ", " + getType(i) + " " + builder); 430 sortingHelper.sort(test[i]); 431 checkSorted(test[i]); 432 } 433 } 434 } 435 out.println(); 436 } 437 testWithCheckSum(int length, TestRandom random)438 private void testWithCheckSum(int length, TestRandom random) { 439 for (int m = 1; m <= length; m <<= 1) { 440 for (UnsortedBuilder builder : UnsortedBuilder.values()) { 441 builder.build((int[]) gold[0], m, random); 442 convertData(length); 443 444 for (int i = 0; i < test.length; i++) { 445 printTestName("Test with check sum", random, length, 446 ", m = " + m + ", " + getType(i) + " " + builder); 447 sortingHelper.sort(test[i]); 448 checkWithCheckSum(test[i], gold[i]); 449 } 450 } 451 } 452 out.println(); 453 } 454 testWithScrambling(int length, TestRandom random)455 private void testWithScrambling(int length, TestRandom random) { 456 for (int m = 1; m <= length; m <<= 1) { 457 for (SortedBuilder builder : SortedBuilder.values()) { 458 builder.build((int[]) gold[0], m); 459 convertData(length); 460 461 for (int i = 0; i < test.length; i++) { 462 printTestName("Test with scrambling", random, length, 463 ", m = " + m + ", " + getType(i) + " " + builder); 464 scramble(test[i], random); 465 sortingHelper.sort(test[i]); 466 compare(test[i], gold[i]); 467 } 468 } 469 } 470 out.println(); 471 } 472 testNegativeZero(int length, TestRandom random)473 private void testNegativeZero(int length, TestRandom random) { 474 for (int i = 5; i < test.length; i++) { 475 printTestName("Test negative zero -0.0", random, length, " " + getType(i)); 476 477 NegativeZeroBuilder builder = NegativeZeroBuilder.values()[i - 5]; 478 builder.build(test[i], random); 479 480 sortingHelper.sort(test[i]); 481 checkNegativeZero(test[i]); 482 } 483 out.println(); 484 } 485 testFloatingPointSorting(int length, TestRandom random)486 private void testFloatingPointSorting(int length, TestRandom random) { 487 if (length < 2) { 488 return; 489 } 490 final int MAX = 13; 491 492 for (int a = 0; a < MAX; a++) { 493 for (int g = 0; g < MAX; g++) { 494 for (int z = 0; z < MAX; z++) { 495 for (int n = 0; n < MAX; n++) { 496 for (int p = 0; p < MAX; p++) { 497 if (a + g + z + n + p != length) { 498 continue; 499 } 500 for (int i = 5; i < test.length; i++) { 501 printTestName("Test float-pointing sorting", random, length, 502 ", a = " + a + ", g = " + g + ", z = " + z + 503 ", n = " + n + ", p = " + p + ", " + getType( 504 i)); 505 FloatingPointBuilder builder = 506 FloatingPointBuilder.values()[i - 5]; 507 builder.build(gold[i], a, g, z, n, p, random); 508 copy(test[i], gold[i]); 509 scramble(test[i], random); 510 sortingHelper.sort(test[i]); 511 compare(test[i], gold[i], a, n, g); 512 } 513 } 514 } 515 } 516 } 517 } 518 519 for (int m = 13; m > 4; m--) { 520 int t = length / m; 521 int g = t, z = t, n = t, p = t; 522 int a = length - g - z - n - p; 523 524 for (int i = 5; i < test.length; i++) { 525 printTestName("Test float-pointing sorting", random, length, 526 ", a = " + a + ", g = " + g + ", z = " + z + 527 ", n = " + n + ", p = " + p + ", " + getType(i)); 528 FloatingPointBuilder builder = FloatingPointBuilder.values()[i - 5]; 529 builder.build(gold[i], a, g, z, n, p, random); 530 copy(test[i], gold[i]); 531 scramble(test[i], random); 532 sortingHelper.sort(test[i]); 533 compare(test[i], gold[i], a, n, g); 534 } 535 } 536 out.println(); 537 } 538 prepareSubArray(int[] a, int fromIndex, int toIndex)539 private void prepareSubArray(int[] a, int fromIndex, int toIndex) { 540 for (int i = 0; i < fromIndex; i++) { 541 a[i] = A380; 542 } 543 int middle = (fromIndex + toIndex) >>> 1; 544 int k = 0; 545 546 for (int i = fromIndex; i < middle; i++) { 547 a[i] = k++; 548 } 549 550 for (int i = middle; i < toIndex; i++) { 551 a[i] = k--; 552 } 553 554 for (int i = toIndex; i < a.length; i++) { 555 a[i] = B747; 556 } 557 } 558 scramble(Object a, Random random)559 private void scramble(Object a, Random random) { 560 if (a instanceof int[]) { 561 scramble((int[]) a, random); 562 } else if (a instanceof long[]) { 563 scramble((long[]) a, random); 564 } else if (a instanceof byte[]) { 565 scramble((byte[]) a, random); 566 } else if (a instanceof char[]) { 567 scramble((char[]) a, random); 568 } else if (a instanceof short[]) { 569 scramble((short[]) a, random); 570 } else if (a instanceof float[]) { 571 scramble((float[]) a, random); 572 } else if (a instanceof double[]) { 573 scramble((double[]) a, random); 574 } else { 575 fail("Unknown type of array: " + a.getClass().getName()); 576 } 577 } 578 scramble(int[] a, Random random)579 private void scramble(int[] a, Random random) { 580 for (int i = 0; i < a.length * 7; i++) { 581 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 582 } 583 } 584 scramble(long[] a, Random random)585 private void scramble(long[] a, Random random) { 586 for (int i = 0; i < a.length * 7; i++) { 587 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 588 } 589 } 590 scramble(byte[] a, Random random)591 private void scramble(byte[] a, Random random) { 592 for (int i = 0; i < a.length * 7; i++) { 593 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 594 } 595 } 596 scramble(char[] a, Random random)597 private void scramble(char[] a, Random random) { 598 for (int i = 0; i < a.length * 7; i++) { 599 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 600 } 601 } 602 scramble(short[] a, Random random)603 private void scramble(short[] a, Random random) { 604 for (int i = 0; i < a.length * 7; i++) { 605 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 606 } 607 } 608 scramble(float[] a, Random random)609 private void scramble(float[] a, Random random) { 610 for (int i = 0; i < a.length * 7; i++) { 611 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 612 } 613 } 614 scramble(double[] a, Random random)615 private void scramble(double[] a, Random random) { 616 for (int i = 0; i < a.length * 7; i++) { 617 swap(a, random.nextInt(a.length), random.nextInt(a.length)); 618 } 619 } 620 swap(int[] a, int i, int j)621 private void swap(int[] a, int i, int j) { 622 int t = a[i]; 623 a[i] = a[j]; 624 a[j] = t; 625 } 626 swap(long[] a, int i, int j)627 private void swap(long[] a, int i, int j) { 628 long t = a[i]; 629 a[i] = a[j]; 630 a[j] = t; 631 } 632 swap(byte[] a, int i, int j)633 private void swap(byte[] a, int i, int j) { 634 byte t = a[i]; 635 a[i] = a[j]; 636 a[j] = t; 637 } 638 swap(char[] a, int i, int j)639 private void swap(char[] a, int i, int j) { 640 char t = a[i]; 641 a[i] = a[j]; 642 a[j] = t; 643 } 644 swap(short[] a, int i, int j)645 private void swap(short[] a, int i, int j) { 646 short t = a[i]; 647 a[i] = a[j]; 648 a[j] = t; 649 } 650 swap(float[] a, int i, int j)651 private void swap(float[] a, int i, int j) { 652 float t = a[i]; 653 a[i] = a[j]; 654 a[j] = t; 655 } 656 swap(double[] a, int i, int j)657 private void swap(double[] a, int i, int j) { 658 double t = a[i]; 659 a[i] = a[j]; 660 a[j] = t; 661 } 662 checkWithCheckSum(Object test, Object gold)663 private void checkWithCheckSum(Object test, Object gold) { 664 checkSorted(test); 665 checkCheckSum(test, gold); 666 } 667 fail(String message)668 private void fail(String message) { 669 err.format("\n*** TEST FAILED ***\n\n%s\n\n", message); 670 throw new RuntimeException("Test failed"); 671 } 672 checkNegativeZero(Object a)673 private void checkNegativeZero(Object a) { 674 if (a instanceof float[]) { 675 checkNegativeZero((float[]) a); 676 } else if (a instanceof double[]) { 677 checkNegativeZero((double[]) a); 678 } else { 679 fail("Unknown type of array: " + a.getClass().getName()); 680 } 681 } 682 checkNegativeZero(float[] a)683 private void checkNegativeZero(float[] a) { 684 for (int i = 0; i < a.length - 1; i++) { 685 if (Float.floatToRawIntBits(a[i]) == 0 && Float.floatToRawIntBits(a[i + 1]) < 0) { 686 fail(a[i] + " before " + a[i + 1] + " at position " + i); 687 } 688 } 689 } 690 checkNegativeZero(double[] a)691 private void checkNegativeZero(double[] a) { 692 for (int i = 0; i < a.length - 1; i++) { 693 if (Double.doubleToRawLongBits(a[i]) == 0 && Double.doubleToRawLongBits(a[i + 1]) 694 < 0) { 695 fail(a[i] + " before " + a[i + 1] + " at position " + i); 696 } 697 } 698 } 699 compare(Object a, Object b, int numNaN, int numNeg, int numNegZero)700 private void compare(Object a, Object b, int numNaN, int numNeg, int numNegZero) { 701 if (a instanceof float[]) { 702 compare((float[]) a, (float[]) b, numNaN, numNeg, numNegZero); 703 } else if (a instanceof double[]) { 704 compare((double[]) a, (double[]) b, numNaN, numNeg, numNegZero); 705 } else { 706 fail("Unknown type of array: " + a.getClass().getName()); 707 } 708 } 709 compare(float[] a, float[] b, int numNaN, int numNeg, int numNegZero)710 private void compare(float[] a, float[] b, int numNaN, int numNeg, int numNegZero) { 711 for (int i = a.length - numNaN; i < a.length; i++) { 712 if (a[i] == a[i]) { 713 fail("There must be NaN instead of " + a[i] + " at position " + i); 714 } 715 } 716 final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f); 717 718 for (int i = numNeg; i < numNeg + numNegZero; i++) { 719 if (NEGATIVE_ZERO != Float.floatToIntBits(a[i])) { 720 fail("There must be -0.0 instead of " + a[i] + " at position " + i); 721 } 722 } 723 724 for (int i = 0; i < a.length - numNaN; i++) { 725 if (a[i] != b[i]) { 726 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 727 } 728 } 729 } 730 compare(double[] a, double[] b, int numNaN, int numNeg, int numNegZero)731 private void compare(double[] a, double[] b, int numNaN, int numNeg, int numNegZero) { 732 for (int i = a.length - numNaN; i < a.length; i++) { 733 if (a[i] == a[i]) { 734 fail("There must be NaN instead of " + a[i] + " at position " + i); 735 } 736 } 737 final long NEGATIVE_ZERO = Double.doubleToLongBits(-0.0d); 738 739 for (int i = numNeg; i < numNeg + numNegZero; i++) { 740 if (NEGATIVE_ZERO != Double.doubleToLongBits(a[i])) { 741 fail("There must be -0.0 instead of " + a[i] + " at position " + i); 742 } 743 } 744 745 for (int i = 0; i < a.length - numNaN; i++) { 746 if (a[i] != b[i]) { 747 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 748 } 749 } 750 } 751 compare(Object a, Object b)752 private void compare(Object a, Object b) { 753 if (a instanceof int[]) { 754 compare((int[]) a, (int[]) b); 755 } else if (a instanceof long[]) { 756 compare((long[]) a, (long[]) b); 757 } else if (a instanceof byte[]) { 758 compare((byte[]) a, (byte[]) b); 759 } else if (a instanceof char[]) { 760 compare((char[]) a, (char[]) b); 761 } else if (a instanceof short[]) { 762 compare((short[]) a, (short[]) b); 763 } else if (a instanceof float[]) { 764 compare((float[]) a, (float[]) b); 765 } else if (a instanceof double[]) { 766 compare((double[]) a, (double[]) b); 767 } else { 768 fail("Unknown type of array: " + a.getClass().getName()); 769 } 770 } 771 compare(int[] a, int[] b)772 private void compare(int[] a, int[] b) { 773 for (int i = 0; i < a.length; i++) { 774 if (a[i] != b[i]) { 775 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 776 } 777 } 778 } 779 compare(long[] a, long[] b)780 private void compare(long[] a, long[] b) { 781 for (int i = 0; i < a.length; i++) { 782 if (a[i] != b[i]) { 783 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 784 } 785 } 786 } 787 compare(byte[] a, byte[] b)788 private void compare(byte[] a, byte[] b) { 789 for (int i = 0; i < a.length; i++) { 790 if (a[i] != b[i]) { 791 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 792 } 793 } 794 } 795 compare(char[] a, char[] b)796 private void compare(char[] a, char[] b) { 797 for (int i = 0; i < a.length; i++) { 798 if (a[i] != b[i]) { 799 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 800 } 801 } 802 } 803 compare(short[] a, short[] b)804 private void compare(short[] a, short[] b) { 805 for (int i = 0; i < a.length; i++) { 806 if (a[i] != b[i]) { 807 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 808 } 809 } 810 } 811 compare(float[] a, float[] b)812 private void compare(float[] a, float[] b) { 813 for (int i = 0; i < a.length; i++) { 814 if (a[i] != b[i]) { 815 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 816 } 817 } 818 } 819 compare(double[] a, double[] b)820 private void compare(double[] a, double[] b) { 821 for (int i = 0; i < a.length; i++) { 822 if (a[i] != b[i]) { 823 fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i); 824 } 825 } 826 } 827 getType(int i)828 private String getType(int i) { 829 Object a = test[i]; 830 831 if (a instanceof int[]) { 832 return "INT "; 833 } 834 if (a instanceof long[]) { 835 return "LONG "; 836 } 837 if (a instanceof byte[]) { 838 return "BYTE "; 839 } 840 if (a instanceof char[]) { 841 return "CHAR "; 842 } 843 if (a instanceof short[]) { 844 return "SHORT "; 845 } 846 if (a instanceof float[]) { 847 return "FLOAT "; 848 } 849 if (a instanceof double[]) { 850 return "DOUBLE"; 851 } 852 fail("Unknown type of array: " + a.getClass().getName()); 853 return null; 854 } 855 checkSorted(Object a)856 private void checkSorted(Object a) { 857 if (a instanceof int[]) { 858 checkSorted((int[]) a); 859 } else if (a instanceof long[]) { 860 checkSorted((long[]) a); 861 } else if (a instanceof byte[]) { 862 checkSorted((byte[]) a); 863 } else if (a instanceof char[]) { 864 checkSorted((char[]) a); 865 } else if (a instanceof short[]) { 866 checkSorted((short[]) a); 867 } else if (a instanceof float[]) { 868 checkSorted((float[]) a); 869 } else if (a instanceof double[]) { 870 checkSorted((double[]) a); 871 } else { 872 fail("Unknown type of array: " + a.getClass().getName()); 873 } 874 } 875 checkSorted(int[] a)876 private void checkSorted(int[] a) { 877 for (int i = 0; i < a.length - 1; i++) { 878 if (a[i] > a[i + 1]) { 879 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 880 + 1]); 881 } 882 } 883 } 884 checkSorted(long[] a)885 private void checkSorted(long[] a) { 886 for (int i = 0; i < a.length - 1; i++) { 887 if (a[i] > a[i + 1]) { 888 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 889 + 1]); 890 } 891 } 892 } 893 checkSorted(byte[] a)894 private void checkSorted(byte[] a) { 895 for (int i = 0; i < a.length - 1; i++) { 896 if (a[i] > a[i + 1]) { 897 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 898 + 1]); 899 } 900 } 901 } 902 checkSorted(char[] a)903 private void checkSorted(char[] a) { 904 for (int i = 0; i < a.length - 1; i++) { 905 if (a[i] > a[i + 1]) { 906 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 907 + 1]); 908 } 909 } 910 } 911 checkSorted(short[] a)912 private void checkSorted(short[] a) { 913 for (int i = 0; i < a.length - 1; i++) { 914 if (a[i] > a[i + 1]) { 915 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 916 + 1]); 917 } 918 } 919 } 920 checkSorted(float[] a)921 private void checkSorted(float[] a) { 922 for (int i = 0; i < a.length - 1; i++) { 923 if (a[i] > a[i + 1]) { 924 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 925 + 1]); 926 } 927 } 928 } 929 checkSorted(double[] a)930 private void checkSorted(double[] a) { 931 for (int i = 0; i < a.length - 1; i++) { 932 if (a[i] > a[i + 1]) { 933 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 934 + 1]); 935 } 936 } 937 } 938 checkCheckSum(Object test, Object gold)939 private void checkCheckSum(Object test, Object gold) { 940 if (checkSumXor(test) != checkSumXor(gold)) { 941 fail("Original and sorted arrays are not identical [^]"); 942 } 943 if (checkSumPlus(test) != checkSumPlus(gold)) { 944 fail("Original and sorted arrays are not identical [+]"); 945 } 946 } 947 checkSumXor(Object a)948 private int checkSumXor(Object a) { 949 if (a instanceof int[]) { 950 return checkSumXor((int[]) a); 951 } 952 if (a instanceof long[]) { 953 return checkSumXor((long[]) a); 954 } 955 if (a instanceof byte[]) { 956 return checkSumXor((byte[]) a); 957 } 958 if (a instanceof char[]) { 959 return checkSumXor((char[]) a); 960 } 961 if (a instanceof short[]) { 962 return checkSumXor((short[]) a); 963 } 964 if (a instanceof float[]) { 965 return checkSumXor((float[]) a); 966 } 967 if (a instanceof double[]) { 968 return checkSumXor((double[]) a); 969 } 970 fail("Unknown type of array: " + a.getClass().getName()); 971 return -1; 972 } 973 checkSumXor(int[] a)974 private int checkSumXor(int[] a) { 975 int checkSum = 0; 976 977 for (int e : a) { 978 checkSum ^= e; 979 } 980 return checkSum; 981 } 982 checkSumXor(long[] a)983 private int checkSumXor(long[] a) { 984 long checkSum = 0; 985 986 for (long e : a) { 987 checkSum ^= e; 988 } 989 return (int) checkSum; 990 } 991 checkSumXor(byte[] a)992 private int checkSumXor(byte[] a) { 993 byte checkSum = 0; 994 995 for (byte e : a) { 996 checkSum ^= e; 997 } 998 return (int) checkSum; 999 } 1000 checkSumXor(char[] a)1001 private int checkSumXor(char[] a) { 1002 char checkSum = 0; 1003 1004 for (char e : a) { 1005 checkSum ^= e; 1006 } 1007 return (int) checkSum; 1008 } 1009 checkSumXor(short[] a)1010 private int checkSumXor(short[] a) { 1011 short checkSum = 0; 1012 1013 for (short e : a) { 1014 checkSum ^= e; 1015 } 1016 return (int) checkSum; 1017 } 1018 checkSumXor(float[] a)1019 private int checkSumXor(float[] a) { 1020 int checkSum = 0; 1021 1022 for (float e : a) { 1023 checkSum ^= (int) e; 1024 } 1025 return checkSum; 1026 } 1027 checkSumXor(double[] a)1028 private int checkSumXor(double[] a) { 1029 int checkSum = 0; 1030 1031 for (double e : a) { 1032 checkSum ^= (int) e; 1033 } 1034 return checkSum; 1035 } 1036 checkSumPlus(Object a)1037 private int checkSumPlus(Object a) { 1038 if (a instanceof int[]) { 1039 return checkSumPlus((int[]) a); 1040 } 1041 if (a instanceof long[]) { 1042 return checkSumPlus((long[]) a); 1043 } 1044 if (a instanceof byte[]) { 1045 return checkSumPlus((byte[]) a); 1046 } 1047 if (a instanceof char[]) { 1048 return checkSumPlus((char[]) a); 1049 } 1050 if (a instanceof short[]) { 1051 return checkSumPlus((short[]) a); 1052 } 1053 if (a instanceof float[]) { 1054 return checkSumPlus((float[]) a); 1055 } 1056 if (a instanceof double[]) { 1057 return checkSumPlus((double[]) a); 1058 } 1059 fail("Unknown type of array: " + a.getClass().getName()); 1060 return -1; 1061 } 1062 checkSumPlus(int[] a)1063 private int checkSumPlus(int[] a) { 1064 int checkSum = 0; 1065 1066 for (int e : a) { 1067 checkSum += e; 1068 } 1069 return checkSum; 1070 } 1071 checkSumPlus(long[] a)1072 private int checkSumPlus(long[] a) { 1073 long checkSum = 0; 1074 1075 for (long e : a) { 1076 checkSum += e; 1077 } 1078 return (int) checkSum; 1079 } 1080 checkSumPlus(byte[] a)1081 private int checkSumPlus(byte[] a) { 1082 byte checkSum = 0; 1083 1084 for (byte e : a) { 1085 checkSum += e; 1086 } 1087 return (int) checkSum; 1088 } 1089 checkSumPlus(char[] a)1090 private int checkSumPlus(char[] a) { 1091 char checkSum = 0; 1092 1093 for (char e : a) { 1094 checkSum += e; 1095 } 1096 return (int) checkSum; 1097 } 1098 checkSumPlus(short[] a)1099 private int checkSumPlus(short[] a) { 1100 short checkSum = 0; 1101 1102 for (short e : a) { 1103 checkSum += e; 1104 } 1105 return (int) checkSum; 1106 } 1107 checkSumPlus(float[] a)1108 private int checkSumPlus(float[] a) { 1109 int checkSum = 0; 1110 1111 for (float e : a) { 1112 checkSum += (int) e; 1113 } 1114 return checkSum; 1115 } 1116 checkSumPlus(double[] a)1117 private int checkSumPlus(double[] a) { 1118 int checkSum = 0; 1119 1120 for (double e : a) { 1121 checkSum += (int) e; 1122 } 1123 return checkSum; 1124 } 1125 sortByInsertionSort(Object a)1126 private void sortByInsertionSort(Object a) { 1127 if (a instanceof int[]) { 1128 sortByInsertionSort((int[]) a); 1129 } else if (a instanceof long[]) { 1130 sortByInsertionSort((long[]) a); 1131 } else if (a instanceof byte[]) { 1132 sortByInsertionSort((byte[]) a); 1133 } else if (a instanceof char[]) { 1134 sortByInsertionSort((char[]) a); 1135 } else if (a instanceof short[]) { 1136 sortByInsertionSort((short[]) a); 1137 } else if (a instanceof float[]) { 1138 sortByInsertionSort((float[]) a); 1139 } else if (a instanceof double[]) { 1140 sortByInsertionSort((double[]) a); 1141 } else { 1142 fail("Unknown type of array: " + a.getClass().getName()); 1143 } 1144 } 1145 sortByInsertionSort(int[] a)1146 private void sortByInsertionSort(int[] a) { 1147 for (int j, i = 1; i < a.length; i++) { 1148 int ai = a[i]; 1149 1150 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1151 a[j + 1] = a[j]; 1152 } 1153 a[j + 1] = ai; 1154 } 1155 } 1156 sortByInsertionSort(long[] a)1157 private void sortByInsertionSort(long[] a) { 1158 for (int j, i = 1; i < a.length; i++) { 1159 long ai = a[i]; 1160 1161 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1162 a[j + 1] = a[j]; 1163 } 1164 a[j + 1] = ai; 1165 } 1166 } 1167 sortByInsertionSort(byte[] a)1168 private void sortByInsertionSort(byte[] a) { 1169 for (int j, i = 1; i < a.length; i++) { 1170 byte ai = a[i]; 1171 1172 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1173 a[j + 1] = a[j]; 1174 } 1175 a[j + 1] = ai; 1176 } 1177 } 1178 sortByInsertionSort(char[] a)1179 private void sortByInsertionSort(char[] a) { 1180 for (int j, i = 1; i < a.length; i++) { 1181 char ai = a[i]; 1182 1183 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1184 a[j + 1] = a[j]; 1185 } 1186 a[j + 1] = ai; 1187 } 1188 } 1189 sortByInsertionSort(short[] a)1190 private void sortByInsertionSort(short[] a) { 1191 for (int j, i = 1; i < a.length; i++) { 1192 short ai = a[i]; 1193 1194 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1195 a[j + 1] = a[j]; 1196 } 1197 a[j + 1] = ai; 1198 } 1199 } 1200 sortByInsertionSort(float[] a)1201 private void sortByInsertionSort(float[] a) { 1202 for (int j, i = 1; i < a.length; i++) { 1203 float ai = a[i]; 1204 1205 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1206 a[j + 1] = a[j]; 1207 } 1208 a[j + 1] = ai; 1209 } 1210 } 1211 sortByInsertionSort(double[] a)1212 private void sortByInsertionSort(double[] a) { 1213 for (int j, i = 1; i < a.length; i++) { 1214 double ai = a[i]; 1215 1216 for (j = i - 1; j >= 0 && ai < a[j]; j--) { 1217 a[j + 1] = a[j]; 1218 } 1219 a[j + 1] = ai; 1220 } 1221 } 1222 checkSubArray(Object a, int fromIndex, int toIndex)1223 private void checkSubArray(Object a, int fromIndex, int toIndex) { 1224 if (a instanceof int[]) { 1225 checkSubArray((int[]) a, fromIndex, toIndex); 1226 } else if (a instanceof long[]) { 1227 checkSubArray((long[]) a, fromIndex, toIndex); 1228 } else if (a instanceof byte[]) { 1229 checkSubArray((byte[]) a, fromIndex, toIndex); 1230 } else if (a instanceof char[]) { 1231 checkSubArray((char[]) a, fromIndex, toIndex); 1232 } else if (a instanceof short[]) { 1233 checkSubArray((short[]) a, fromIndex, toIndex); 1234 } else if (a instanceof float[]) { 1235 checkSubArray((float[]) a, fromIndex, toIndex); 1236 } else if (a instanceof double[]) { 1237 checkSubArray((double[]) a, fromIndex, toIndex); 1238 } else { 1239 fail("Unknown type of array: " + a.getClass().getName()); 1240 } 1241 } 1242 checkSubArray(int[] a, int fromIndex, int toIndex)1243 private void checkSubArray(int[] a, int fromIndex, int toIndex) { 1244 for (int i = 0; i < fromIndex; i++) { 1245 if (a[i] != A380) { 1246 fail("Range sort changes left element at position " + i + hex(a[i], A380)); 1247 } 1248 } 1249 1250 for (int i = fromIndex; i < toIndex - 1; i++) { 1251 if (a[i] > a[i + 1]) { 1252 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1253 + 1]); 1254 } 1255 } 1256 1257 for (int i = toIndex; i < a.length; i++) { 1258 if (a[i] != B747) { 1259 fail("Range sort changes right element at position " + i + hex(a[i], B747)); 1260 } 1261 } 1262 } 1263 checkSubArray(long[] a, int fromIndex, int toIndex)1264 private void checkSubArray(long[] a, int fromIndex, int toIndex) { 1265 for (int i = 0; i < fromIndex; i++) { 1266 if (a[i] != (long) A380) { 1267 fail("Range sort changes left element at position " + i + hex(a[i], A380)); 1268 } 1269 } 1270 1271 for (int i = fromIndex; i < toIndex - 1; i++) { 1272 if (a[i] > a[i + 1]) { 1273 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1274 + 1]); 1275 } 1276 } 1277 1278 for (int i = toIndex; i < a.length; i++) { 1279 if (a[i] != (long) B747) { 1280 fail("Range sort changes right element at position " + i + hex(a[i], B747)); 1281 } 1282 } 1283 } 1284 checkSubArray(byte[] a, int fromIndex, int toIndex)1285 private void checkSubArray(byte[] a, int fromIndex, int toIndex) { 1286 for (int i = 0; i < fromIndex; i++) { 1287 if (a[i] != (byte) A380) { 1288 fail("Range sort changes left element at position " + i + hex(a[i], A380)); 1289 } 1290 } 1291 1292 for (int i = fromIndex; i < toIndex - 1; i++) { 1293 if (a[i] > a[i + 1]) { 1294 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1295 + 1]); 1296 } 1297 } 1298 1299 for (int i = toIndex; i < a.length; i++) { 1300 if (a[i] != (byte) B747) { 1301 fail("Range sort changes right element at position " + i + hex(a[i], B747)); 1302 } 1303 } 1304 } 1305 checkSubArray(char[] a, int fromIndex, int toIndex)1306 private void checkSubArray(char[] a, int fromIndex, int toIndex) { 1307 for (int i = 0; i < fromIndex; i++) { 1308 if (a[i] != (char) A380) { 1309 fail("Range sort changes left element at position " + i + hex(a[i], A380)); 1310 } 1311 } 1312 1313 for (int i = fromIndex; i < toIndex - 1; i++) { 1314 if (a[i] > a[i + 1]) { 1315 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1316 + 1]); 1317 } 1318 } 1319 1320 for (int i = toIndex; i < a.length; i++) { 1321 if (a[i] != (char) B747) { 1322 fail("Range sort changes right element at position " + i + hex(a[i], B747)); 1323 } 1324 } 1325 } 1326 checkSubArray(short[] a, int fromIndex, int toIndex)1327 private void checkSubArray(short[] a, int fromIndex, int toIndex) { 1328 for (int i = 0; i < fromIndex; i++) { 1329 if (a[i] != (short) A380) { 1330 fail("Range sort changes left element at position " + i + hex(a[i], A380)); 1331 } 1332 } 1333 1334 for (int i = fromIndex; i < toIndex - 1; i++) { 1335 if (a[i] > a[i + 1]) { 1336 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1337 + 1]); 1338 } 1339 } 1340 1341 for (int i = toIndex; i < a.length; i++) { 1342 if (a[i] != (short) B747) { 1343 fail("Range sort changes right element at position " + i + hex(a[i], B747)); 1344 } 1345 } 1346 } 1347 checkSubArray(float[] a, int fromIndex, int toIndex)1348 private void checkSubArray(float[] a, int fromIndex, int toIndex) { 1349 for (int i = 0; i < fromIndex; i++) { 1350 if (a[i] != (float) A380) { 1351 fail("Range sort changes left element at position " + i + hex((long) a[i], 1352 A380)); 1353 } 1354 } 1355 1356 for (int i = fromIndex; i < toIndex - 1; i++) { 1357 if (a[i] > a[i + 1]) { 1358 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1359 + 1]); 1360 } 1361 } 1362 1363 for (int i = toIndex; i < a.length; i++) { 1364 if (a[i] != (float) B747) { 1365 fail("Range sort changes right element at position " + i + hex((long) a[i], 1366 B747)); 1367 } 1368 } 1369 } 1370 checkSubArray(double[] a, int fromIndex, int toIndex)1371 private void checkSubArray(double[] a, int fromIndex, int toIndex) { 1372 for (int i = 0; i < fromIndex; i++) { 1373 if (a[i] != (double) A380) { 1374 fail("Range sort changes left element at position " + i + hex((long) a[i], 1375 A380)); 1376 } 1377 } 1378 1379 for (int i = fromIndex; i < toIndex - 1; i++) { 1380 if (a[i] > a[i + 1]) { 1381 fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i 1382 + 1]); 1383 } 1384 } 1385 1386 for (int i = toIndex; i < a.length; i++) { 1387 if (a[i] != (double) B747) { 1388 fail("Range sort changes right element at position " + i + hex((long) a[i], 1389 B747)); 1390 } 1391 } 1392 } 1393 checkRange(Object a, int m)1394 private void checkRange(Object a, int m) { 1395 if (a instanceof int[]) { 1396 checkRange((int[]) a, m); 1397 } else if (a instanceof long[]) { 1398 checkRange((long[]) a, m); 1399 } else if (a instanceof byte[]) { 1400 checkRange((byte[]) a, m); 1401 } else if (a instanceof char[]) { 1402 checkRange((char[]) a, m); 1403 } else if (a instanceof short[]) { 1404 checkRange((short[]) a, m); 1405 } else if (a instanceof float[]) { 1406 checkRange((float[]) a, m); 1407 } else if (a instanceof double[]) { 1408 checkRange((double[]) a, m); 1409 } else { 1410 fail("Unknown type of array: " + a.getClass().getName()); 1411 } 1412 } 1413 checkRange(int[] a, int m)1414 private void checkRange(int[] a, int m) { 1415 try { 1416 sortingHelper.sort(a, m + 1, m); 1417 fail(sortingHelper + " does not throw IllegalArgumentException " + 1418 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1419 } catch (IllegalArgumentException iae) { 1420 try { 1421 sortingHelper.sort(a, -m, a.length); 1422 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1423 "as expected: fromIndex = " + (-m)); 1424 } catch (ArrayIndexOutOfBoundsException aoe) { 1425 try { 1426 sortingHelper.sort(a, 0, a.length + m); 1427 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1428 "as expected: toIndex = " + (a.length + m)); 1429 } catch (ArrayIndexOutOfBoundsException expected) { 1430 } 1431 } 1432 } 1433 } 1434 checkRange(long[] a, int m)1435 private void checkRange(long[] a, int m) { 1436 try { 1437 sortingHelper.sort(a, m + 1, m); 1438 fail(sortingHelper + " does not throw IllegalArgumentException " + 1439 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1440 } catch (IllegalArgumentException iae) { 1441 try { 1442 sortingHelper.sort(a, -m, a.length); 1443 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1444 "as expected: fromIndex = " + (-m)); 1445 } catch (ArrayIndexOutOfBoundsException aoe) { 1446 try { 1447 sortingHelper.sort(a, 0, a.length + m); 1448 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1449 "as expected: toIndex = " + (a.length + m)); 1450 } catch (ArrayIndexOutOfBoundsException expected) { 1451 } 1452 } 1453 } 1454 } 1455 checkRange(byte[] a, int m)1456 private void checkRange(byte[] a, int m) { 1457 try { 1458 sortingHelper.sort(a, m + 1, m); 1459 fail(sortingHelper + " does not throw IllegalArgumentException " + 1460 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1461 } catch (IllegalArgumentException iae) { 1462 try { 1463 sortingHelper.sort(a, -m, a.length); 1464 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1465 "as expected: fromIndex = " + (-m)); 1466 } catch (ArrayIndexOutOfBoundsException aoe) { 1467 try { 1468 sortingHelper.sort(a, 0, a.length + m); 1469 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1470 "as expected: toIndex = " + (a.length + m)); 1471 } catch (ArrayIndexOutOfBoundsException expected) { 1472 } 1473 } 1474 } 1475 } 1476 checkRange(char[] a, int m)1477 private void checkRange(char[] a, int m) { 1478 try { 1479 sortingHelper.sort(a, m + 1, m); 1480 fail(sortingHelper + " does not throw IllegalArgumentException " + 1481 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1482 } catch (IllegalArgumentException iae) { 1483 try { 1484 sortingHelper.sort(a, -m, a.length); 1485 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1486 "as expected: fromIndex = " + (-m)); 1487 } catch (ArrayIndexOutOfBoundsException aoe) { 1488 try { 1489 sortingHelper.sort(a, 0, a.length + m); 1490 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1491 "as expected: toIndex = " + (a.length + m)); 1492 } catch (ArrayIndexOutOfBoundsException expected) { 1493 } 1494 } 1495 } 1496 } 1497 checkRange(short[] a, int m)1498 private void checkRange(short[] a, int m) { 1499 try { 1500 sortingHelper.sort(a, m + 1, m); 1501 fail(sortingHelper + " does not throw IllegalArgumentException " + 1502 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1503 } catch (IllegalArgumentException iae) { 1504 try { 1505 sortingHelper.sort(a, -m, a.length); 1506 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1507 "as expected: fromIndex = " + (-m)); 1508 } catch (ArrayIndexOutOfBoundsException aoe) { 1509 try { 1510 sortingHelper.sort(a, 0, a.length + m); 1511 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1512 "as expected: toIndex = " + (a.length + m)); 1513 } catch (ArrayIndexOutOfBoundsException expected) { 1514 } 1515 } 1516 } 1517 } 1518 checkRange(float[] a, int m)1519 private void checkRange(float[] a, int m) { 1520 try { 1521 sortingHelper.sort(a, m + 1, m); 1522 fail(sortingHelper + " does not throw IllegalArgumentException " + 1523 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1524 } catch (IllegalArgumentException iae) { 1525 try { 1526 sortingHelper.sort(a, -m, a.length); 1527 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1528 "as expected: fromIndex = " + (-m)); 1529 } catch (ArrayIndexOutOfBoundsException aoe) { 1530 try { 1531 sortingHelper.sort(a, 0, a.length + m); 1532 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1533 "as expected: toIndex = " + (a.length + m)); 1534 } catch (ArrayIndexOutOfBoundsException expected) { 1535 } 1536 } 1537 } 1538 } 1539 checkRange(double[] a, int m)1540 private void checkRange(double[] a, int m) { 1541 try { 1542 sortingHelper.sort(a, m + 1, m); 1543 fail(sortingHelper + " does not throw IllegalArgumentException " + 1544 "as expected: fromIndex = " + (m + 1) + " toIndex = " + m); 1545 } catch (IllegalArgumentException iae) { 1546 try { 1547 sortingHelper.sort(a, -m, a.length); 1548 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1549 "as expected: fromIndex = " + (-m)); 1550 } catch (ArrayIndexOutOfBoundsException aoe) { 1551 try { 1552 sortingHelper.sort(a, 0, a.length + m); 1553 fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " + 1554 "as expected: toIndex = " + (a.length + m)); 1555 } catch (ArrayIndexOutOfBoundsException expected) { 1556 } 1557 } 1558 } 1559 } 1560 copy(Object dst, Object src)1561 private void copy(Object dst, Object src) { 1562 if (src instanceof float[]) { 1563 copy((float[]) dst, (float[]) src); 1564 } else if (src instanceof double[]) { 1565 copy((double[]) dst, (double[]) src); 1566 } else { 1567 fail("Unknown type of array: " + src.getClass().getName()); 1568 } 1569 } 1570 copy(float[] dst, float[] src)1571 private void copy(float[] dst, float[] src) { 1572 System.arraycopy(src, 0, dst, 0, src.length); 1573 } 1574 copy(double[] dst, double[] src)1575 private void copy(double[] dst, double[] src) { 1576 System.arraycopy(src, 0, dst, 0, src.length); 1577 } 1578 printTestName(String test, TestRandom random, int length)1579 private void printTestName(String test, TestRandom random, int length) { 1580 printTestName(test, random, length, ""); 1581 } 1582 createData(int length)1583 private void createData(int length) { 1584 gold = new Object[]{ 1585 new int[length], new long[length], 1586 new byte[length], new char[length], new short[length], 1587 new float[length], new double[length] 1588 }; 1589 1590 test = new Object[]{ 1591 new int[length], new long[length], 1592 new byte[length], new char[length], new short[length], 1593 new float[length], new double[length] 1594 }; 1595 } 1596 convertData(int length)1597 private void convertData(int length) { 1598 for (int i = 1; i < gold.length; i++) { 1599 TypeConverter converter = TypeConverter.values()[i - 1]; 1600 converter.convert((int[]) gold[0], gold[i]); 1601 } 1602 1603 for (int i = 0; i < gold.length; i++) { 1604 System.arraycopy(gold[i], 0, test[i], 0, length); 1605 } 1606 } 1607 hex(long a, int b)1608 private String hex(long a, int b) { 1609 return ": " + Long.toHexString(a) + ", must be " + Integer.toHexString(b); 1610 } 1611 printTestName(String test, TestRandom random, int length, String message)1612 private void printTestName(String test, TestRandom random, int length, String message) { 1613 out.println("[" + sortingHelper + "] '" + test + 1614 "' length = " + length + ", random = " + random + message); 1615 } 1616 } 1617 1618 private static enum TypeConverter { 1619 LONG { convert(int[] src, Object dst)1620 void convert(int[] src, Object dst) { 1621 long[] b = (long[]) dst; 1622 1623 for (int i = 0; i < src.length; i++) { 1624 b[i] = (long) src[i]; 1625 } 1626 } 1627 }, 1628 1629 BYTE { convert(int[] src, Object dst)1630 void convert(int[] src, Object dst) { 1631 byte[] b = (byte[]) dst; 1632 1633 for (int i = 0; i < src.length; i++) { 1634 b[i] = (byte) src[i]; 1635 } 1636 } 1637 }, 1638 1639 CHAR { convert(int[] src, Object dst)1640 void convert(int[] src, Object dst) { 1641 char[] b = (char[]) dst; 1642 1643 for (int i = 0; i < src.length; i++) { 1644 b[i] = (char) src[i]; 1645 } 1646 } 1647 }, 1648 1649 SHORT { convert(int[] src, Object dst)1650 void convert(int[] src, Object dst) { 1651 short[] b = (short[]) dst; 1652 1653 for (int i = 0; i < src.length; i++) { 1654 b[i] = (short) src[i]; 1655 } 1656 } 1657 }, 1658 1659 FLOAT { convert(int[] src, Object dst)1660 void convert(int[] src, Object dst) { 1661 float[] b = (float[]) dst; 1662 1663 for (int i = 0; i < src.length; i++) { 1664 b[i] = (float) src[i]; 1665 } 1666 } 1667 }, 1668 1669 DOUBLE { convert(int[] src, Object dst)1670 void convert(int[] src, Object dst) { 1671 double[] b = (double[]) dst; 1672 1673 for (int i = 0; i < src.length; i++) { 1674 b[i] = (double) src[i]; 1675 } 1676 } 1677 }; 1678 convert(int[] src, Object dst)1679 abstract void convert(int[] src, Object dst); 1680 } 1681 1682 private static enum SortedBuilder { 1683 STEPS { build(int[] a, int m)1684 void build(int[] a, int m) { 1685 for (int i = 0; i < m; i++) { 1686 a[i] = 0; 1687 } 1688 1689 for (int i = m; i < a.length; i++) { 1690 a[i] = 1; 1691 } 1692 } 1693 }; 1694 build(int[] a, int m)1695 abstract void build(int[] a, int m); 1696 } 1697 1698 private static enum UnsortedBuilder { 1699 RANDOM { build(int[] a, int m, Random random)1700 void build(int[] a, int m, Random random) { 1701 for (int i = 0; i < a.length; i++) { 1702 a[i] = random.nextInt(); 1703 } 1704 } 1705 }, 1706 1707 ASCENDING { build(int[] a, int m, Random random)1708 void build(int[] a, int m, Random random) { 1709 for (int i = 0; i < a.length; i++) { 1710 a[i] = m + i; 1711 } 1712 } 1713 }, 1714 1715 DESCENDING { build(int[] a, int m, Random random)1716 void build(int[] a, int m, Random random) { 1717 for (int i = 0; i < a.length; i++) { 1718 a[i] = a.length - m - i; 1719 } 1720 } 1721 }, 1722 1723 EQUAL { build(int[] a, int m, Random random)1724 void build(int[] a, int m, Random random) { 1725 for (int i = 0; i < a.length; i++) { 1726 a[i] = m; 1727 } 1728 } 1729 }, 1730 1731 SAW { build(int[] a, int m, Random random)1732 void build(int[] a, int m, Random random) { 1733 int incCount = 1; 1734 int decCount = a.length; 1735 int i = 0; 1736 int period = m--; 1737 1738 while (true) { 1739 for (int k = 1; k <= period; k++) { 1740 if (i >= a.length) { 1741 return; 1742 } 1743 a[i++] = incCount++; 1744 } 1745 period += m; 1746 1747 for (int k = 1; k <= period; k++) { 1748 if (i >= a.length) { 1749 return; 1750 } 1751 a[i++] = decCount--; 1752 } 1753 period += m; 1754 } 1755 } 1756 }, 1757 1758 REPEATED { build(int[] a, int m, Random random)1759 void build(int[] a, int m, Random random) { 1760 for (int i = 0; i < a.length; i++) { 1761 a[i] = i % m; 1762 } 1763 } 1764 }, 1765 1766 DUPLICATED { build(int[] a, int m, Random random)1767 void build(int[] a, int m, Random random) { 1768 for (int i = 0; i < a.length; i++) { 1769 a[i] = random.nextInt(m); 1770 } 1771 } 1772 }, 1773 1774 ORGAN_PIPES { build(int[] a, int m, Random random)1775 void build(int[] a, int m, Random random) { 1776 int middle = a.length / (m + 1); 1777 1778 for (int i = 0; i < middle; i++) { 1779 a[i] = i; 1780 } 1781 1782 for (int i = middle; i < a.length; i++) { 1783 a[i] = a.length - i - 1; 1784 } 1785 } 1786 }, 1787 1788 STAGGER { build(int[] a, int m, Random random)1789 void build(int[] a, int m, Random random) { 1790 for (int i = 0; i < a.length; i++) { 1791 a[i] = (i * m + i) % a.length; 1792 } 1793 } 1794 }, 1795 1796 PLATEAU { build(int[] a, int m, Random random)1797 void build(int[] a, int m, Random random) { 1798 for (int i = 0; i < a.length; i++) { 1799 a[i] = Math.min(i, m); 1800 } 1801 } 1802 }, 1803 1804 SHUFFLE { build(int[] a, int m, Random random)1805 void build(int[] a, int m, Random random) { 1806 int x = 0, y = 0; 1807 1808 for (int i = 0; i < a.length; i++) { 1809 a[i] = random.nextBoolean() ? (x += 2) : (y += 2); 1810 } 1811 } 1812 }, 1813 1814 LATCH { build(int[] a, int m, Random random)1815 void build(int[] a, int m, Random random) { 1816 int max = a.length / m; 1817 max = max < 2 ? 2 : max; 1818 1819 for (int i = 0; i < a.length; i++) { 1820 a[i] = i % max; 1821 } 1822 } 1823 }; 1824 1825 abstract void build(int[] a, int m, Random random); 1826 } 1827 1828 private static enum MergingBuilder { 1829 ASCENDING { 1830 void build(int[] a, int m) { 1831 int period = a.length / m; 1832 int v = 1, i = 0; 1833 1834 for (int k = 0; k < m; k++) { 1835 v = 1; 1836 1837 for (int p = 0; p < period; p++) { 1838 a[i++] = v++; 1839 } 1840 } 1841 1842 for (int j = i; j < a.length - 1; j++) { 1843 a[j] = v++; 1844 } 1845 1846 a[a.length - 1] = 0; 1847 } 1848 }, 1849 1850 DESCENDING { 1851 void build(int[] a, int m) { 1852 int period = a.length / m; 1853 int v = -1, i = 0; 1854 1855 for (int k = 0; k < m; k++) { 1856 v = -1; 1857 1858 for (int p = 0; p < period; p++) { 1859 a[i++] = v--; 1860 } 1861 } 1862 1863 for (int j = i; j < a.length - 1; j++) { 1864 a[j] = v--; 1865 } 1866 1867 a[a.length - 1] = 0; 1868 } 1869 }, 1870 1871 POINT { 1872 void build(int[] a, int m) { 1873 for (int i = 0; i < a.length; i++) { 1874 a[i] = 0; 1875 } 1876 a[a.length / 2] = m; 1877 } 1878 }, 1879 1880 LINE { 1881 void build(int[] a, int m) { 1882 for (int i = 0; i < a.length; i++) { 1883 a[i] = i; 1884 } 1885 reverse(a, 0, a.length - 1); 1886 } 1887 }, 1888 1889 PEARL { 1890 void build(int[] a, int m) { 1891 for (int i = 0; i < a.length; i++) { 1892 a[i] = i; 1893 } 1894 reverse(a, 0, 2); 1895 } 1896 }, 1897 1898 RING { 1899 void build(int[] a, int m) { 1900 int k1 = a.length / 3; 1901 int k2 = a.length / 3 * 2; 1902 int level = a.length / 3; 1903 1904 for (int i = 0, k = level; i < k1; i++) { 1905 a[i] = k--; 1906 } 1907 1908 for (int i = k1; i < k2; i++) { 1909 a[i] = 0; 1910 } 1911 1912 for (int i = k2, k = level; i < a.length; i++) { 1913 a[i] = k--; 1914 } 1915 } 1916 }; 1917 1918 abstract void build(int[] a, int m); 1919 1920 private static void reverse(int[] a, int lo, int hi) { 1921 for (--hi; lo < hi; ) { 1922 int tmp = a[lo]; 1923 a[lo++] = a[hi]; 1924 a[hi--] = tmp; 1925 } 1926 } 1927 } 1928 1929 private static enum NegativeZeroBuilder { 1930 FLOAT { 1931 void build(Object o, Random random) { 1932 float[] a = (float[]) o; 1933 1934 for (int i = 0; i < a.length; i++) { 1935 a[i] = random.nextBoolean() ? -0.0f : 0.0f; 1936 } 1937 } 1938 }, 1939 1940 DOUBLE { 1941 void build(Object o, Random random) { 1942 double[] a = (double[]) o; 1943 1944 for (int i = 0; i < a.length; i++) { 1945 a[i] = random.nextBoolean() ? -0.0d : 0.0d; 1946 } 1947 } 1948 }; 1949 1950 abstract void build(Object o, Random random); 1951 } 1952 1953 private static enum FloatingPointBuilder { 1954 FLOAT { 1955 void build(Object o, int a, int g, int z, int n, int p, Random random) { 1956 float negativeValue = -random.nextFloat(); 1957 float positiveValue = random.nextFloat(); 1958 float[] x = (float[]) o; 1959 int fromIndex = 0; 1960 1961 writeValue(x, negativeValue, fromIndex, n); 1962 fromIndex += n; 1963 1964 writeValue(x, -0.0f, fromIndex, g); 1965 fromIndex += g; 1966 1967 writeValue(x, 0.0f, fromIndex, z); 1968 fromIndex += z; 1969 1970 writeValue(x, positiveValue, fromIndex, p); 1971 fromIndex += p; 1972 1973 writeValue(x, Float.NaN, fromIndex, a); 1974 } 1975 }, 1976 1977 DOUBLE { 1978 void build(Object o, int a, int g, int z, int n, int p, Random random) { 1979 double negativeValue = -random.nextFloat(); 1980 double positiveValue = random.nextFloat(); 1981 double[] x = (double[]) o; 1982 int fromIndex = 0; 1983 1984 writeValue(x, negativeValue, fromIndex, n); 1985 fromIndex += n; 1986 1987 writeValue(x, -0.0d, fromIndex, g); 1988 fromIndex += g; 1989 1990 writeValue(x, 0.0d, fromIndex, z); 1991 fromIndex += z; 1992 1993 writeValue(x, positiveValue, fromIndex, p); 1994 fromIndex += p; 1995 1996 writeValue(x, Double.NaN, fromIndex, a); 1997 } 1998 }; 1999 2000 abstract void build(Object o, int a, int g, int z, int n, int p, Random random); 2001 2002 private static void writeValue(float[] a, float value, int fromIndex, int count) { 2003 for (int i = fromIndex; i < fromIndex + count; i++) { 2004 a[i] = value; 2005 } 2006 } 2007 2008 private static void writeValue(double[] a, double value, int fromIndex, int count) { 2009 for (int i = fromIndex; i < fromIndex + count; i++) { 2010 a[i] = value; 2011 } 2012 } 2013 } 2014 2015 private static Comparator<Pair> pairComparator = new Comparator<Pair>() { 2016 2017 @Override 2018 public int compare(Pair p1, Pair p2) { 2019 return p1.compareTo(p2); 2020 } 2021 }; 2022 2023 private static class Pair implements Comparable<Pair> { 2024 2025 private Pair(int key, int value) { 2026 this.key = key; 2027 this.value = value; 2028 } 2029 2030 int getKey() { 2031 return key; 2032 } 2033 2034 int getValue() { 2035 return value; 2036 } 2037 2038 @Override 2039 public int compareTo(Pair pair) { 2040 return Integer.compare(key, pair.key); 2041 } 2042 2043 @Override 2044 public String toString() { 2045 return "(" + key + ", " + value + ")"; 2046 } 2047 2048 private int key; 2049 private int value; 2050 } 2051 2052 private static class TestRandom extends Random { 2053 2054 private static final TestRandom BABA = new TestRandom(0xBABA); 2055 private static final TestRandom DEDA = new TestRandom(0xDEDA); 2056 private static final TestRandom C0FFEE = new TestRandom(0xC0FFEE); 2057 2058 private TestRandom(long seed) { 2059 super(seed); 2060 this.seed = Long.toHexString(seed).toUpperCase(); 2061 } 2062 2063 @Override 2064 public String toString() { 2065 return seed; 2066 } 2067 2068 private String seed; 2069 } 2070 } 2071