Path: blob/master/test/jdk/java/util/Arrays/Sorting.java
41149 views
/*1* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @compile/module=java.base java/util/SortingHelper.java26* @bug 6880672 6896573 6899694 6976036 7013585 7018258 8003981 822629727* @build Sorting28* @run main Sorting -shortrun29* @summary Exercise Arrays.sort, Arrays.parallelSort30*31* @author Vladimir Yaroslavskiy32* @author Jon Bentley33* @author Josh Bloch34*/3536import java.io.PrintStream;37import java.util.Comparator;38import java.util.Random;39import java.util.SortingHelper;4041public class Sorting {4243private static final PrintStream out = System.out;44private static final PrintStream err = System.err;4546// Array lengths used in a long run (default)47private static final int[] LONG_RUN_LENGTHS = {481, 3, 8, 21, 55, 100, 1_000, 10_000, 100_000 };4950// Array lengths used in a short run51private static final int[] SHORT_RUN_LENGTHS = {521, 8, 55, 100, 10_000 };5354// Random initial values used in a long run (default)55private static final TestRandom[] LONG_RUN_RANDOMS = {56TestRandom.BABA, TestRandom.DEDA, TestRandom.C0FFEE };5758// Random initial values used in a short run59private static final TestRandom[] SHORT_RUN_RANDOMS = {60TestRandom.C0FFEE };6162// Constants used in subarray sorting63private static final int A380 = 0xA380;64private static final int B747 = 0xB747;6566private final SortingHelper sortingHelper;67private final TestRandom[] randoms;68private final int[] lengths;69private Object[] gold;70private Object[] test;7172public static void main(String[] args) {73long start = System.currentTimeMillis();74boolean shortRun = args.length > 0 && args[0].equals("-shortrun");7576int[] lengths = shortRun ? SHORT_RUN_LENGTHS : LONG_RUN_LENGTHS;77TestRandom[] randoms = shortRun ? SHORT_RUN_RANDOMS : LONG_RUN_RANDOMS;7879new Sorting(SortingHelper.DUAL_PIVOT_QUICKSORT, randoms, lengths).testCore();80new Sorting(SortingHelper.PARALLEL_SORT, randoms, lengths).testCore();81new Sorting(SortingHelper.HEAP_SORT, randoms, lengths).testBasic();82new Sorting(SortingHelper.ARRAYS_SORT, randoms, lengths).testAll();83new Sorting(SortingHelper.ARRAYS_PARALLEL_SORT, randoms, lengths).testAll();8485long end = System.currentTimeMillis();86out.format("PASSED in %d sec.\n", (end - start) / 1000);87}8889private Sorting(SortingHelper sortingHelper, TestRandom[] randoms, int[] lengths) {90this.sortingHelper = sortingHelper;91this.randoms = randoms;92this.lengths = lengths;93}9495private void testBasic() {96testEmptyArray();9798for (int length : lengths) {99createData(length);100testBasic(length);101}102}103104private void testBasic(int length) {105for (TestRandom random : randoms) {106testWithInsertionSort(length, random);107testWithCheckSum(length, random);108testWithScrambling(length, random);109}110}111112private void testCore() {113for (int length : lengths) {114createData(length);115testCore(length);116}117}118119private void testCore(int length) {120testBasic(length);121122for (TestRandom random : randoms) {123testMergingSort(length, random);124testSubArray(length, random);125testNegativeZero(length, random);126testFloatingPointSorting(length, random);127}128}129130private void testAll() {131for (int length : lengths) {132createData(length);133testAll(length);134}135}136137private void testAll(int length) {138testCore(length);139140for (TestRandom random : randoms) {141testRange(length, random);142testStability(length, random);143}144}145146private void testEmptyArray() {147testEmptyAndNullIntArray();148testEmptyAndNullLongArray();149testEmptyAndNullByteArray();150testEmptyAndNullCharArray();151testEmptyAndNullShortArray();152testEmptyAndNullFloatArray();153testEmptyAndNullDoubleArray();154}155156private void testStability(int length, TestRandom random) {157printTestName("Test stability", random, length);158159Pair[] a = build(length, random);160sortingHelper.sort(a);161checkSorted(a);162checkStable(a);163164a = build(length, random);165sortingHelper.sort(a, pairComparator);166checkSorted(a);167checkStable(a);168169out.println();170}171172private void testEmptyAndNullIntArray() {173sortingHelper.sort(new int[] {});174sortingHelper.sort(new int[] {}, 0, 0);175176try {177sortingHelper.sort(null);178} catch (NullPointerException expected) {179try {180sortingHelper.sort(null, 0, 0);181} catch (NullPointerException expected2) {182return;183}184fail(sortingHelper + "(int[],fromIndex,toIndex) shouldn't " +185"catch null array");186}187fail(sortingHelper + "(int[]) shouldn't catch null array");188}189190private void testEmptyAndNullLongArray() {191sortingHelper.sort(new long[] {});192sortingHelper.sort(new long[] {}, 0, 0);193194try {195sortingHelper.sort(null);196} catch (NullPointerException expected) {197try {198sortingHelper.sort(null, 0, 0);199} catch (NullPointerException expected2) {200return;201}202fail(sortingHelper + "(long[],fromIndex,toIndex) shouldn't " +203"catch null array");204}205fail(sortingHelper + "(long[]) shouldn't catch null array");206}207208private void testEmptyAndNullByteArray() {209sortingHelper.sort(new byte[] {});210sortingHelper.sort(new byte[] {}, 0, 0);211212try {213sortingHelper.sort(null);214} catch (NullPointerException expected) {215try {216sortingHelper.sort(null, 0, 0);217} catch (NullPointerException expected2) {218return;219}220fail(sortingHelper + "(byte[],fromIndex,toIndex) shouldn't " +221"catch null array");222}223fail(sortingHelper + "(byte[]) shouldn't catch null array");224}225226private void testEmptyAndNullCharArray() {227sortingHelper.sort(new char[] {});228sortingHelper.sort(new char[] {}, 0, 0);229230try {231sortingHelper.sort(null);232} catch (NullPointerException expected) {233try {234sortingHelper.sort(null, 0, 0);235} catch (NullPointerException expected2) {236return;237}238fail(sortingHelper + "(char[],fromIndex,toIndex) shouldn't " +239"catch null array");240}241fail(sortingHelper + "(char[]) shouldn't catch null array");242}243244private void testEmptyAndNullShortArray() {245sortingHelper.sort(new short[] {});246sortingHelper.sort(new short[] {}, 0, 0);247248try {249sortingHelper.sort(null);250} catch (NullPointerException expected) {251try {252sortingHelper.sort(null, 0, 0);253} catch (NullPointerException expected2) {254return;255}256fail(sortingHelper + "(short[],fromIndex,toIndex) shouldn't " +257"catch null array");258}259fail(sortingHelper + "(short[]) shouldn't catch null array");260}261262private void testEmptyAndNullFloatArray() {263sortingHelper.sort(new float[] {});264sortingHelper.sort(new float[] {}, 0, 0);265266try {267sortingHelper.sort(null);268} catch (NullPointerException expected) {269try {270sortingHelper.sort(null, 0, 0);271} catch (NullPointerException expected2) {272return;273}274fail(sortingHelper + "(float[],fromIndex,toIndex) shouldn't " +275"catch null array");276}277fail(sortingHelper + "(float[]) shouldn't catch null array");278}279280private void testEmptyAndNullDoubleArray() {281sortingHelper.sort(new double[] {});282sortingHelper.sort(new double[] {}, 0, 0);283284try {285sortingHelper.sort(null);286} catch (NullPointerException expected) {287try {288sortingHelper.sort(null, 0, 0);289} catch (NullPointerException expected2) {290return;291}292fail(sortingHelper + "(double[],fromIndex,toIndex) shouldn't " +293"catch null array");294}295fail(sortingHelper + "(double[]) shouldn't catch null array");296}297298private void testSubArray(int length, TestRandom random) {299if (length < 4) {300return;301}302for (int m = 1; m < length / 2; m <<= 1) {303int fromIndex = m;304int toIndex = length - m;305306prepareSubArray((int[]) gold[0], fromIndex, toIndex);307convertData(length);308309for (int i = 0; i < test.length; i++) {310printTestName("Test subarray", random, length,311", m = " + m + ", " + getType(i));312sortingHelper.sort(test[i], fromIndex, toIndex);313checkSubArray(test[i], fromIndex, toIndex);314}315}316out.println();317}318319private void testRange(int length, TestRandom random) {320if (length < 2) {321return;322}323for (int m = 1; m < length; m <<= 1) {324for (int i = 1; i <= length; i++) {325((int[]) gold[0]) [i - 1] = i % m + m % i;326}327convertData(length);328329for (int i = 0; i < test.length; i++) {330printTestName("Test range check", random, length,331", m = " + m + ", " + getType(i));332checkRange(test[i], m);333}334}335out.println();336}337338private void checkSorted(Pair[] a) {339for (int i = 0; i < a.length - 1; i++) {340if (a[i].getKey() > a[i + 1].getKey()) {341fail("Array is not sorted at " + i + "-th position: " +342a[i].getKey() + " and " + a[i + 1].getKey());343}344}345}346347private void checkStable(Pair[] a) {348for (int i = 0; i < a.length / 4; ) {349int key1 = a[i].getKey();350int value1 = a[i++].getValue();351int key2 = a[i].getKey();352int value2 = a[i++].getValue();353int key3 = a[i].getKey();354int value3 = a[i++].getValue();355int key4 = a[i].getKey();356int value4 = a[i++].getValue();357358if (!(key1 == key2 && key2 == key3 && key3 == key4)) {359fail("Keys are different " + key1 + ", " + key2 + ", " +360key3 + ", " + key4 + " at position " + i);361}362if (!(value1 < value2 && value2 < value3 && value3 < value4)) {363fail("Sorting is not stable at position " + i +364". Second values have been changed: " + value1 + ", " +365value2 + ", " + value3 + ", " + value4);366}367}368}369370private Pair[] build(int length, Random random) {371Pair[] a = new Pair[length * 4];372373for (int i = 0; i < a.length; ) {374int key = random.nextInt();375a[i++] = new Pair(key, 1);376a[i++] = new Pair(key, 2);377a[i++] = new Pair(key, 3);378a[i++] = new Pair(key, 4);379}380return a;381}382383private void testWithInsertionSort(int length, TestRandom random) {384if (length > 1000) {385return;386}387for (int m = 1; m <= length; m <<= 1) {388for (UnsortedBuilder builder : UnsortedBuilder.values()) {389builder.build((int[]) gold[0], m, random);390convertData(length);391392for (int i = 0; i < test.length; i++) {393printTestName("Test with insertion sort", random, length,394", m = " + m + ", " + getType(i) + " " + builder);395sortingHelper.sort(test[i]);396sortByInsertionSort(gold[i]);397compare(test[i], gold[i]);398}399}400}401out.println();402}403404private void testMergingSort(int length, TestRandom random) {405if (length < (4 << 10)) { // DualPivotQuicksort.MIN_TRY_MERGE_SIZE406return;407}408final int PERIOD = 50;409410for (int m = PERIOD - 2; m <= PERIOD + 2; m++) {411for (MergingBuilder builder : MergingBuilder.values()) {412builder.build((int[]) gold[0], m);413convertData(length);414415for (int i = 0; i < test.length; i++) {416printTestName("Test merging sort", random, length,417", m = " + m + ", " + getType(i) + " " + builder);418sortingHelper.sort(test[i]);419checkSorted(test[i]);420}421}422}423out.println();424}425426private void testWithCheckSum(int length, TestRandom random) {427for (int m = 1; m <= length; m <<= 1) {428for (UnsortedBuilder builder : UnsortedBuilder.values()) {429builder.build((int[]) gold[0], m, random);430convertData(length);431432for (int i = 0; i < test.length; i++) {433printTestName("Test with check sum", random, length,434", m = " + m + ", " + getType(i) + " " + builder);435sortingHelper.sort(test[i]);436checkWithCheckSum(test[i], gold[i]);437}438}439}440out.println();441}442443private void testWithScrambling(int length, TestRandom random) {444for (int m = 1; m <= length; m <<= 1) {445for (SortedBuilder builder : SortedBuilder.values()) {446builder.build((int[]) gold[0], m);447convertData(length);448449for (int i = 0; i < test.length; i++) {450printTestName("Test with scrambling", random, length,451", m = " + m + ", " + getType(i) + " " + builder);452scramble(test[i], random);453sortingHelper.sort(test[i]);454compare(test[i], gold[i]);455}456}457}458out.println();459}460461private void testNegativeZero(int length, TestRandom random) {462for (int i = 5; i < test.length; i++) {463printTestName("Test negative zero -0.0", random, length, " " + getType(i));464465NegativeZeroBuilder builder = NegativeZeroBuilder.values() [i - 5];466builder.build(test[i], random);467468sortingHelper.sort(test[i]);469checkNegativeZero(test[i]);470}471out.println();472}473474private void testFloatingPointSorting(int length, TestRandom random) {475if (length < 2) {476return;477}478final int MAX = 13;479480for (int a = 0; a < MAX; a++) {481for (int g = 0; g < MAX; g++) {482for (int z = 0; z < MAX; z++) {483for (int n = 0; n < MAX; n++) {484for (int p = 0; p < MAX; p++) {485if (a + g + z + n + p != length) {486continue;487}488for (int i = 5; i < test.length; i++) {489printTestName("Test float-pointing sorting", random, length,490", a = " + a + ", g = " + g + ", z = " + z +491", n = " + n + ", p = " + p + ", " + getType(i));492FloatingPointBuilder builder = FloatingPointBuilder.values()[i - 5];493builder.build(gold[i], a, g, z, n, p, random);494copy(test[i], gold[i]);495scramble(test[i], random);496sortingHelper.sort(test[i]);497compare(test[i], gold[i], a, n, g);498}499}500}501}502}503}504505for (int m = 13; m > 4; m--) {506int t = length / m;507int g = t, z = t, n = t, p = t;508int a = length - g - z - n - p;509510for (int i = 5; i < test.length; i++) {511printTestName("Test float-pointing sorting", random, length,512", a = " + a + ", g = " + g + ", z = " + z +513", n = " + n + ", p = " + p + ", " + getType(i));514FloatingPointBuilder builder = FloatingPointBuilder.values() [i - 5];515builder.build(gold[i], a, g, z, n, p, random);516copy(test[i], gold[i]);517scramble(test[i], random);518sortingHelper.sort(test[i]);519compare(test[i], gold[i], a, n, g);520}521}522out.println();523}524525private void prepareSubArray(int[] a, int fromIndex, int toIndex) {526for (int i = 0; i < fromIndex; i++) {527a[i] = A380;528}529int middle = (fromIndex + toIndex) >>> 1;530int k = 0;531532for (int i = fromIndex; i < middle; i++) {533a[i] = k++;534}535536for (int i = middle; i < toIndex; i++) {537a[i] = k--;538}539540for (int i = toIndex; i < a.length; i++) {541a[i] = B747;542}543}544545private void scramble(Object a, Random random) {546if (a instanceof int[]) {547scramble((int[]) a, random);548} else if (a instanceof long[]) {549scramble((long[]) a, random);550} else if (a instanceof byte[]) {551scramble((byte[]) a, random);552} else if (a instanceof char[]) {553scramble((char[]) a, random);554} else if (a instanceof short[]) {555scramble((short[]) a, random);556} else if (a instanceof float[]) {557scramble((float[]) a, random);558} else if (a instanceof double[]) {559scramble((double[]) a, random);560} else {561fail("Unknown type of array: " + a.getClass().getName());562}563}564565private void scramble(int[] a, Random random) {566for (int i = 0; i < a.length * 7; i++) {567swap(a, random.nextInt(a.length), random.nextInt(a.length));568}569}570571private void scramble(long[] a, Random random) {572for (int i = 0; i < a.length * 7; i++) {573swap(a, random.nextInt(a.length), random.nextInt(a.length));574}575}576577private void scramble(byte[] a, Random random) {578for (int i = 0; i < a.length * 7; i++) {579swap(a, random.nextInt(a.length), random.nextInt(a.length));580}581}582583private void scramble(char[] a, Random random) {584for (int i = 0; i < a.length * 7; i++) {585swap(a, random.nextInt(a.length), random.nextInt(a.length));586}587}588589private void scramble(short[] a, Random random) {590for (int i = 0; i < a.length * 7; i++) {591swap(a, random.nextInt(a.length), random.nextInt(a.length));592}593}594595private void scramble(float[] a, Random random) {596for (int i = 0; i < a.length * 7; i++) {597swap(a, random.nextInt(a.length), random.nextInt(a.length));598}599}600601private void scramble(double[] a, Random random) {602for (int i = 0; i < a.length * 7; i++) {603swap(a, random.nextInt(a.length), random.nextInt(a.length));604}605}606607private void swap(int[] a, int i, int j) {608int t = a[i]; a[i] = a[j]; a[j] = t;609}610611private void swap(long[] a, int i, int j) {612long t = a[i]; a[i] = a[j]; a[j] = t;613}614615private void swap(byte[] a, int i, int j) {616byte t = a[i]; a[i] = a[j]; a[j] = t;617}618619private void swap(char[] a, int i, int j) {620char t = a[i]; a[i] = a[j]; a[j] = t;621}622623private void swap(short[] a, int i, int j) {624short t = a[i]; a[i] = a[j]; a[j] = t;625}626627private void swap(float[] a, int i, int j) {628float t = a[i]; a[i] = a[j]; a[j] = t;629}630631private void swap(double[] a, int i, int j) {632double t = a[i]; a[i] = a[j]; a[j] = t;633}634635private void checkWithCheckSum(Object test, Object gold) {636checkSorted(test);637checkCheckSum(test, gold);638}639640private void fail(String message) {641err.format("\n*** TEST FAILED ***\n\n%s\n\n", message);642throw new RuntimeException("Test failed");643}644645private void checkNegativeZero(Object a) {646if (a instanceof float[]) {647checkNegativeZero((float[]) a);648} else if (a instanceof double[]) {649checkNegativeZero((double[]) a);650} else {651fail("Unknown type of array: " + a.getClass().getName());652}653}654655private void checkNegativeZero(float[] a) {656for (int i = 0; i < a.length - 1; i++) {657if (Float.floatToRawIntBits(a[i]) == 0 && Float.floatToRawIntBits(a[i + 1]) < 0) {658fail(a[i] + " before " + a[i + 1] + " at position " + i);659}660}661}662663private void checkNegativeZero(double[] a) {664for (int i = 0; i < a.length - 1; i++) {665if (Double.doubleToRawLongBits(a[i]) == 0 && Double.doubleToRawLongBits(a[i + 1]) < 0) {666fail(a[i] + " before " + a[i + 1] + " at position " + i);667}668}669}670671private void compare(Object a, Object b, int numNaN, int numNeg, int numNegZero) {672if (a instanceof float[]) {673compare((float[]) a, (float[]) b, numNaN, numNeg, numNegZero);674} else if (a instanceof double[]) {675compare((double[]) a, (double[]) b, numNaN, numNeg, numNegZero);676} else {677fail("Unknown type of array: " + a.getClass().getName());678}679}680681private void compare(float[] a, float[] b, int numNaN, int numNeg, int numNegZero) {682for (int i = a.length - numNaN; i < a.length; i++) {683if (a[i] == a[i]) {684fail("There must be NaN instead of " + a[i] + " at position " + i);685}686}687final int NEGATIVE_ZERO = Float.floatToIntBits(-0.0f);688689for (int i = numNeg; i < numNeg + numNegZero; i++) {690if (NEGATIVE_ZERO != Float.floatToIntBits(a[i])) {691fail("There must be -0.0 instead of " + a[i] + " at position " + i);692}693}694695for (int i = 0; i < a.length - numNaN; i++) {696if (a[i] != b[i]) {697fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);698}699}700}701702private void compare(double[] a, double[] b, int numNaN, int numNeg, int numNegZero) {703for (int i = a.length - numNaN; i < a.length; i++) {704if (a[i] == a[i]) {705fail("There must be NaN instead of " + a[i] + " at position " + i);706}707}708final long NEGATIVE_ZERO = Double.doubleToLongBits(-0.0d);709710for (int i = numNeg; i < numNeg + numNegZero; i++) {711if (NEGATIVE_ZERO != Double.doubleToLongBits(a[i])) {712fail("There must be -0.0 instead of " + a[i] + " at position " + i);713}714}715716for (int i = 0; i < a.length - numNaN; i++) {717if (a[i] != b[i]) {718fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);719}720}721}722723private void compare(Object a, Object b) {724if (a instanceof int[]) {725compare((int[]) a, (int[]) b);726} else if (a instanceof long[]) {727compare((long[]) a, (long[]) b);728} else if (a instanceof byte[]) {729compare((byte[]) a, (byte[]) b);730} else if (a instanceof char[]) {731compare((char[]) a, (char[]) b);732} else if (a instanceof short[]) {733compare((short[]) a, (short[]) b);734} else if (a instanceof float[]) {735compare((float[]) a, (float[]) b);736} else if (a instanceof double[]) {737compare((double[]) a, (double[]) b);738} else {739fail("Unknown type of array: " + a.getClass().getName());740}741}742743private void compare(int[] a, int[] b) {744for (int i = 0; i < a.length; i++) {745if (a[i] != b[i]) {746fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);747}748}749}750751private void compare(long[] a, long[] b) {752for (int i = 0; i < a.length; i++) {753if (a[i] != b[i]) {754fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);755}756}757}758759private void compare(byte[] a, byte[] b) {760for (int i = 0; i < a.length; i++) {761if (a[i] != b[i]) {762fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);763}764}765}766767private void compare(char[] a, char[] b) {768for (int i = 0; i < a.length; i++) {769if (a[i] != b[i]) {770fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);771}772}773}774775private void compare(short[] a, short[] b) {776for (int i = 0; i < a.length; i++) {777if (a[i] != b[i]) {778fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);779}780}781}782783private void compare(float[] a, float[] b) {784for (int i = 0; i < a.length; i++) {785if (a[i] != b[i]) {786fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);787}788}789}790791private void compare(double[] a, double[] b) {792for (int i = 0; i < a.length; i++) {793if (a[i] != b[i]) {794fail("There must be " + b[i] + " instead of " + a[i] + " at position " + i);795}796}797}798799private String getType(int i) {800Object a = test[i];801802if (a instanceof int[]) {803return "INT ";804}805if (a instanceof long[]) {806return "LONG ";807}808if (a instanceof byte[]) {809return "BYTE ";810}811if (a instanceof char[]) {812return "CHAR ";813}814if (a instanceof short[]) {815return "SHORT ";816}817if (a instanceof float[]) {818return "FLOAT ";819}820if (a instanceof double[]) {821return "DOUBLE";822}823fail("Unknown type of array: " + a.getClass().getName());824return null;825}826827private void checkSorted(Object a) {828if (a instanceof int[]) {829checkSorted((int[]) a);830} else if (a instanceof long[]) {831checkSorted((long[]) a);832} else if (a instanceof byte[]) {833checkSorted((byte[]) a);834} else if (a instanceof char[]) {835checkSorted((char[]) a);836} else if (a instanceof short[]) {837checkSorted((short[]) a);838} else if (a instanceof float[]) {839checkSorted((float[]) a);840} else if (a instanceof double[]) {841checkSorted((double[]) a);842} else {843fail("Unknown type of array: " + a.getClass().getName());844}845}846847private void checkSorted(int[] a) {848for (int i = 0; i < a.length - 1; i++) {849if (a[i] > a[i + 1]) {850fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);851}852}853}854855private void checkSorted(long[] a) {856for (int i = 0; i < a.length - 1; i++) {857if (a[i] > a[i + 1]) {858fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);859}860}861}862863private void checkSorted(byte[] a) {864for (int i = 0; i < a.length - 1; i++) {865if (a[i] > a[i + 1]) {866fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);867}868}869}870871private void checkSorted(char[] a) {872for (int i = 0; i < a.length - 1; i++) {873if (a[i] > a[i + 1]) {874fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);875}876}877}878879private void checkSorted(short[] a) {880for (int i = 0; i < a.length - 1; i++) {881if (a[i] > a[i + 1]) {882fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);883}884}885}886887private void checkSorted(float[] a) {888for (int i = 0; i < a.length - 1; i++) {889if (a[i] > a[i + 1]) {890fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);891}892}893}894895private void checkSorted(double[] a) {896for (int i = 0; i < a.length - 1; i++) {897if (a[i] > a[i + 1]) {898fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);899}900}901}902903private void checkCheckSum(Object test, Object gold) {904if (checkSumXor(test) != checkSumXor(gold)) {905fail("Original and sorted arrays are not identical [^]");906}907if (checkSumPlus(test) != checkSumPlus(gold)) {908fail("Original and sorted arrays are not identical [+]");909}910}911912private int checkSumXor(Object a) {913if (a instanceof int[]) {914return checkSumXor((int[]) a);915}916if (a instanceof long[]) {917return checkSumXor((long[]) a);918}919if (a instanceof byte[]) {920return checkSumXor((byte[]) a);921}922if (a instanceof char[]) {923return checkSumXor((char[]) a);924}925if (a instanceof short[]) {926return checkSumXor((short[]) a);927}928if (a instanceof float[]) {929return checkSumXor((float[]) a);930}931if (a instanceof double[]) {932return checkSumXor((double[]) a);933}934fail("Unknown type of array: " + a.getClass().getName());935return -1;936}937938private int checkSumXor(int[] a) {939int checkSum = 0;940941for (int e : a) {942checkSum ^= e;943}944return checkSum;945}946947private int checkSumXor(long[] a) {948long checkSum = 0;949950for (long e : a) {951checkSum ^= e;952}953return (int) checkSum;954}955956private int checkSumXor(byte[] a) {957byte checkSum = 0;958959for (byte e : a) {960checkSum ^= e;961}962return (int) checkSum;963}964965private int checkSumXor(char[] a) {966char checkSum = 0;967968for (char e : a) {969checkSum ^= e;970}971return (int) checkSum;972}973974private int checkSumXor(short[] a) {975short checkSum = 0;976977for (short e : a) {978checkSum ^= e;979}980return (int) checkSum;981}982983private int checkSumXor(float[] a) {984int checkSum = 0;985986for (float e : a) {987checkSum ^= (int) e;988}989return checkSum;990}991992private int checkSumXor(double[] a) {993int checkSum = 0;994995for (double e : a) {996checkSum ^= (int) e;997}998return checkSum;999}10001001private int checkSumPlus(Object a) {1002if (a instanceof int[]) {1003return checkSumPlus((int[]) a);1004}1005if (a instanceof long[]) {1006return checkSumPlus((long[]) a);1007}1008if (a instanceof byte[]) {1009return checkSumPlus((byte[]) a);1010}1011if (a instanceof char[]) {1012return checkSumPlus((char[]) a);1013}1014if (a instanceof short[]) {1015return checkSumPlus((short[]) a);1016}1017if (a instanceof float[]) {1018return checkSumPlus((float[]) a);1019}1020if (a instanceof double[]) {1021return checkSumPlus((double[]) a);1022}1023fail("Unknown type of array: " + a.getClass().getName());1024return -1;1025}10261027private int checkSumPlus(int[] a) {1028int checkSum = 0;10291030for (int e : a) {1031checkSum += e;1032}1033return checkSum;1034}10351036private int checkSumPlus(long[] a) {1037long checkSum = 0;10381039for (long e : a) {1040checkSum += e;1041}1042return (int) checkSum;1043}10441045private int checkSumPlus(byte[] a) {1046byte checkSum = 0;10471048for (byte e : a) {1049checkSum += e;1050}1051return (int) checkSum;1052}10531054private int checkSumPlus(char[] a) {1055char checkSum = 0;10561057for (char e : a) {1058checkSum += e;1059}1060return (int) checkSum;1061}10621063private int checkSumPlus(short[] a) {1064short checkSum = 0;10651066for (short e : a) {1067checkSum += e;1068}1069return (int) checkSum;1070}10711072private int checkSumPlus(float[] a) {1073int checkSum = 0;10741075for (float e : a) {1076checkSum += (int) e;1077}1078return checkSum;1079}10801081private int checkSumPlus(double[] a) {1082int checkSum = 0;10831084for (double e : a) {1085checkSum += (int) e;1086}1087return checkSum;1088}10891090private void sortByInsertionSort(Object a) {1091if (a instanceof int[]) {1092sortByInsertionSort((int[]) a);1093} else if (a instanceof long[]) {1094sortByInsertionSort((long[]) a);1095} else if (a instanceof byte[]) {1096sortByInsertionSort((byte[]) a);1097} else if (a instanceof char[]) {1098sortByInsertionSort((char[]) a);1099} else if (a instanceof short[]) {1100sortByInsertionSort((short[]) a);1101} else if (a instanceof float[]) {1102sortByInsertionSort((float[]) a);1103} else if (a instanceof double[]) {1104sortByInsertionSort((double[]) a);1105} else {1106fail("Unknown type of array: " + a.getClass().getName());1107}1108}11091110private void sortByInsertionSort(int[] a) {1111for (int j, i = 1; i < a.length; i++) {1112int ai = a[i];11131114for (j = i - 1; j >= 0 && ai < a[j]; j--) {1115a[j + 1] = a[j];1116}1117a[j + 1] = ai;1118}1119}11201121private void sortByInsertionSort(long[] a) {1122for (int j, i = 1; i < a.length; i++) {1123long ai = a[i];11241125for (j = i - 1; j >= 0 && ai < a[j]; j--) {1126a[j + 1] = a[j];1127}1128a[j + 1] = ai;1129}1130}11311132private void sortByInsertionSort(byte[] a) {1133for (int j, i = 1; i < a.length; i++) {1134byte ai = a[i];11351136for (j = i - 1; j >= 0 && ai < a[j]; j--) {1137a[j + 1] = a[j];1138}1139a[j + 1] = ai;1140}1141}11421143private void sortByInsertionSort(char[] a) {1144for (int j, i = 1; i < a.length; i++) {1145char ai = a[i];11461147for (j = i - 1; j >= 0 && ai < a[j]; j--) {1148a[j + 1] = a[j];1149}1150a[j + 1] = ai;1151}1152}11531154private void sortByInsertionSort(short[] a) {1155for (int j, i = 1; i < a.length; i++) {1156short ai = a[i];11571158for (j = i - 1; j >= 0 && ai < a[j]; j--) {1159a[j + 1] = a[j];1160}1161a[j + 1] = ai;1162}1163}11641165private void sortByInsertionSort(float[] a) {1166for (int j, i = 1; i < a.length; i++) {1167float ai = a[i];11681169for (j = i - 1; j >= 0 && ai < a[j]; j--) {1170a[j + 1] = a[j];1171}1172a[j + 1] = ai;1173}1174}11751176private void sortByInsertionSort(double[] a) {1177for (int j, i = 1; i < a.length; i++) {1178double ai = a[i];11791180for (j = i - 1; j >= 0 && ai < a[j]; j--) {1181a[j + 1] = a[j];1182}1183a[j + 1] = ai;1184}1185}11861187private void checkSubArray(Object a, int fromIndex, int toIndex) {1188if (a instanceof int[]) {1189checkSubArray((int[]) a, fromIndex, toIndex);1190} else if (a instanceof long[]) {1191checkSubArray((long[]) a, fromIndex, toIndex);1192} else if (a instanceof byte[]) {1193checkSubArray((byte[]) a, fromIndex, toIndex);1194} else if (a instanceof char[]) {1195checkSubArray((char[]) a, fromIndex, toIndex);1196} else if (a instanceof short[]) {1197checkSubArray((short[]) a, fromIndex, toIndex);1198} else if (a instanceof float[]) {1199checkSubArray((float[]) a, fromIndex, toIndex);1200} else if (a instanceof double[]) {1201checkSubArray((double[]) a, fromIndex, toIndex);1202} else {1203fail("Unknown type of array: " + a.getClass().getName());1204}1205}12061207private void checkSubArray(int[] a, int fromIndex, int toIndex) {1208for (int i = 0; i < fromIndex; i++) {1209if (a[i] != A380) {1210fail("Range sort changes left element at position " + i + hex(a[i], A380));1211}1212}12131214for (int i = fromIndex; i < toIndex - 1; i++) {1215if (a[i] > a[i + 1]) {1216fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1217}1218}12191220for (int i = toIndex; i < a.length; i++) {1221if (a[i] != B747) {1222fail("Range sort changes right element at position " + i + hex(a[i], B747));1223}1224}1225}12261227private void checkSubArray(long[] a, int fromIndex, int toIndex) {1228for (int i = 0; i < fromIndex; i++) {1229if (a[i] != (long) A380) {1230fail("Range sort changes left element at position " + i + hex(a[i], A380));1231}1232}12331234for (int i = fromIndex; i < toIndex - 1; i++) {1235if (a[i] > a[i + 1]) {1236fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1237}1238}12391240for (int i = toIndex; i < a.length; i++) {1241if (a[i] != (long) B747) {1242fail("Range sort changes right element at position " + i + hex(a[i], B747));1243}1244}1245}12461247private void checkSubArray(byte[] a, int fromIndex, int toIndex) {1248for (int i = 0; i < fromIndex; i++) {1249if (a[i] != (byte) A380) {1250fail("Range sort changes left element at position " + i + hex(a[i], A380));1251}1252}12531254for (int i = fromIndex; i < toIndex - 1; i++) {1255if (a[i] > a[i + 1]) {1256fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1257}1258}12591260for (int i = toIndex; i < a.length; i++) {1261if (a[i] != (byte) B747) {1262fail("Range sort changes right element at position " + i + hex(a[i], B747));1263}1264}1265}12661267private void checkSubArray(char[] a, int fromIndex, int toIndex) {1268for (int i = 0; i < fromIndex; i++) {1269if (a[i] != (char) A380) {1270fail("Range sort changes left element at position " + i + hex(a[i], A380));1271}1272}12731274for (int i = fromIndex; i < toIndex - 1; i++) {1275if (a[i] > a[i + 1]) {1276fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1277}1278}12791280for (int i = toIndex; i < a.length; i++) {1281if (a[i] != (char) B747) {1282fail("Range sort changes right element at position " + i + hex(a[i], B747));1283}1284}1285}12861287private void checkSubArray(short[] a, int fromIndex, int toIndex) {1288for (int i = 0; i < fromIndex; i++) {1289if (a[i] != (short) A380) {1290fail("Range sort changes left element at position " + i + hex(a[i], A380));1291}1292}12931294for (int i = fromIndex; i < toIndex - 1; i++) {1295if (a[i] > a[i + 1]) {1296fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1297}1298}12991300for (int i = toIndex; i < a.length; i++) {1301if (a[i] != (short) B747) {1302fail("Range sort changes right element at position " + i + hex(a[i], B747));1303}1304}1305}13061307private void checkSubArray(float[] a, int fromIndex, int toIndex) {1308for (int i = 0; i < fromIndex; i++) {1309if (a[i] != (float) A380) {1310fail("Range sort changes left element at position " + i + hex((long) a[i], A380));1311}1312}13131314for (int i = fromIndex; i < toIndex - 1; i++) {1315if (a[i] > a[i + 1]) {1316fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1317}1318}13191320for (int i = toIndex; i < a.length; i++) {1321if (a[i] != (float) B747) {1322fail("Range sort changes right element at position " + i + hex((long) a[i], B747));1323}1324}1325}13261327private void checkSubArray(double[] a, int fromIndex, int toIndex) {1328for (int i = 0; i < fromIndex; i++) {1329if (a[i] != (double) A380) {1330fail("Range sort changes left element at position " + i + hex((long) a[i], A380));1331}1332}13331334for (int i = fromIndex; i < toIndex - 1; i++) {1335if (a[i] > a[i + 1]) {1336fail("Array is not sorted at " + i + "-th position: " + a[i] + " and " + a[i + 1]);1337}1338}13391340for (int i = toIndex; i < a.length; i++) {1341if (a[i] != (double) B747) {1342fail("Range sort changes right element at position " + i + hex((long) a[i], B747));1343}1344}1345}13461347private void checkRange(Object a, int m) {1348if (a instanceof int[]) {1349checkRange((int[]) a, m);1350} else if (a instanceof long[]) {1351checkRange((long[]) a, m);1352} else if (a instanceof byte[]) {1353checkRange((byte[]) a, m);1354} else if (a instanceof char[]) {1355checkRange((char[]) a, m);1356} else if (a instanceof short[]) {1357checkRange((short[]) a, m);1358} else if (a instanceof float[]) {1359checkRange((float[]) a, m);1360} else if (a instanceof double[]) {1361checkRange((double[]) a, m);1362} else {1363fail("Unknown type of array: " + a.getClass().getName());1364}1365}13661367private void checkRange(int[] a, int m) {1368try {1369sortingHelper.sort(a, m + 1, m);1370fail(sortingHelper + " does not throw IllegalArgumentException " +1371"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1372} catch (IllegalArgumentException iae) {1373try {1374sortingHelper.sort(a, -m, a.length);1375fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1376"as expected: fromIndex = " + (-m));1377} catch (ArrayIndexOutOfBoundsException aoe) {1378try {1379sortingHelper.sort(a, 0, a.length + m);1380fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1381"as expected: toIndex = " + (a.length + m));1382} catch (ArrayIndexOutOfBoundsException expected) {}1383}1384}1385}13861387private void checkRange(long[] a, int m) {1388try {1389sortingHelper.sort(a, m + 1, m);1390fail(sortingHelper + " does not throw IllegalArgumentException " +1391"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1392} catch (IllegalArgumentException iae) {1393try {1394sortingHelper.sort(a, -m, a.length);1395fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1396"as expected: fromIndex = " + (-m));1397} catch (ArrayIndexOutOfBoundsException aoe) {1398try {1399sortingHelper.sort(a, 0, a.length + m);1400fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1401"as expected: toIndex = " + (a.length + m));1402} catch (ArrayIndexOutOfBoundsException expected) {}1403}1404}1405}14061407private void checkRange(byte[] a, int m) {1408try {1409sortingHelper.sort(a, m + 1, m);1410fail(sortingHelper + " does not throw IllegalArgumentException " +1411"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1412} catch (IllegalArgumentException iae) {1413try {1414sortingHelper.sort(a, -m, a.length);1415fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1416"as expected: fromIndex = " + (-m));1417} catch (ArrayIndexOutOfBoundsException aoe) {1418try {1419sortingHelper.sort(a, 0, a.length + m);1420fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1421"as expected: toIndex = " + (a.length + m));1422} catch (ArrayIndexOutOfBoundsException expected) {}1423}1424}1425}14261427private void checkRange(char[] a, int m) {1428try {1429sortingHelper.sort(a, m + 1, m);1430fail(sortingHelper + " does not throw IllegalArgumentException " +1431"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1432} catch (IllegalArgumentException iae) {1433try {1434sortingHelper.sort(a, -m, a.length);1435fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1436"as expected: fromIndex = " + (-m));1437} catch (ArrayIndexOutOfBoundsException aoe) {1438try {1439sortingHelper.sort(a, 0, a.length + m);1440fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1441"as expected: toIndex = " + (a.length + m));1442} catch (ArrayIndexOutOfBoundsException expected) {}1443}1444}1445}14461447private void checkRange(short[] a, int m) {1448try {1449sortingHelper.sort(a, m + 1, m);1450fail(sortingHelper + " does not throw IllegalArgumentException " +1451"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1452} catch (IllegalArgumentException iae) {1453try {1454sortingHelper.sort(a, -m, a.length);1455fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1456"as expected: fromIndex = " + (-m));1457} catch (ArrayIndexOutOfBoundsException aoe) {1458try {1459sortingHelper.sort(a, 0, a.length + m);1460fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1461"as expected: toIndex = " + (a.length + m));1462} catch (ArrayIndexOutOfBoundsException expected) {}1463}1464}1465}14661467private void checkRange(float[] a, int m) {1468try {1469sortingHelper.sort(a, m + 1, m);1470fail(sortingHelper + " does not throw IllegalArgumentException " +1471"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1472} catch (IllegalArgumentException iae) {1473try {1474sortingHelper.sort(a, -m, a.length);1475fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1476"as expected: fromIndex = " + (-m));1477} catch (ArrayIndexOutOfBoundsException aoe) {1478try {1479sortingHelper.sort(a, 0, a.length + m);1480fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1481"as expected: toIndex = " + (a.length + m));1482} catch (ArrayIndexOutOfBoundsException expected) {}1483}1484}1485}14861487private void checkRange(double[] a, int m) {1488try {1489sortingHelper.sort(a, m + 1, m);1490fail(sortingHelper + " does not throw IllegalArgumentException " +1491"as expected: fromIndex = " + (m + 1) + " toIndex = " + m);1492} catch (IllegalArgumentException iae) {1493try {1494sortingHelper.sort(a, -m, a.length);1495fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1496"as expected: fromIndex = " + (-m));1497} catch (ArrayIndexOutOfBoundsException aoe) {1498try {1499sortingHelper.sort(a, 0, a.length + m);1500fail(sortingHelper + " does not throw ArrayIndexOutOfBoundsException " +1501"as expected: toIndex = " + (a.length + m));1502} catch (ArrayIndexOutOfBoundsException expected) {}1503}1504}1505}15061507private void copy(Object dst, Object src) {1508if (src instanceof float[]) {1509copy((float[]) dst, (float[]) src);1510} else if (src instanceof double[]) {1511copy((double[]) dst, (double[]) src);1512} else {1513fail("Unknown type of array: " + src.getClass().getName());1514}1515}15161517private void copy(float[] dst, float[] src) {1518System.arraycopy(src, 0, dst, 0, src.length);1519}15201521private void copy(double[] dst, double[] src) {1522System.arraycopy(src, 0, dst, 0, src.length);1523}15241525private void printTestName(String test, TestRandom random, int length) {1526printTestName(test, random, length, "");1527}15281529private void createData(int length) {1530gold = new Object[] {1531new int[length], new long[length],1532new byte[length], new char[length], new short[length],1533new float[length], new double[length]1534};15351536test = new Object[] {1537new int[length], new long[length],1538new byte[length], new char[length], new short[length],1539new float[length], new double[length]1540};1541}15421543private void convertData(int length) {1544for (int i = 1; i < gold.length; i++) {1545TypeConverter converter = TypeConverter.values()[i - 1];1546converter.convert((int[])gold[0], gold[i]);1547}15481549for (int i = 0; i < gold.length; i++) {1550System.arraycopy(gold[i], 0, test[i], 0, length);1551}1552}15531554private String hex(long a, int b) {1555return ": " + Long.toHexString(a) + ", must be " + Integer.toHexString(b);1556}15571558private void printTestName(String test, TestRandom random, int length, String message) {1559out.println( "[" + sortingHelper + "] '" + test +1560"' length = " + length + ", random = " + random + message);1561}15621563private static enum TypeConverter {1564LONG {1565void convert(int[] src, Object dst) {1566long[] b = (long[]) dst;15671568for (int i = 0; i < src.length; i++) {1569b[i] = (long) src[i];1570}1571}1572},15731574BYTE {1575void convert(int[] src, Object dst) {1576byte[] b = (byte[]) dst;15771578for (int i = 0; i < src.length; i++) {1579b[i] = (byte) src[i];1580}1581}1582},15831584CHAR {1585void convert(int[] src, Object dst) {1586char[] b = (char[]) dst;15871588for (int i = 0; i < src.length; i++) {1589b[i] = (char) src[i];1590}1591}1592},15931594SHORT {1595void convert(int[] src, Object dst) {1596short[] b = (short[]) dst;15971598for (int i = 0; i < src.length; i++) {1599b[i] = (short) src[i];1600}1601}1602},16031604FLOAT {1605void convert(int[] src, Object dst) {1606float[] b = (float[]) dst;16071608for (int i = 0; i < src.length; i++) {1609b[i] = (float) src[i];1610}1611}1612},16131614DOUBLE {1615void convert(int[] src, Object dst) {1616double[] b = (double[]) dst;16171618for (int i = 0; i < src.length; i++) {1619b[i] = (double) src[i];1620}1621}1622};16231624abstract void convert(int[] src, Object dst);1625}16261627private static enum SortedBuilder {1628STEPS {1629void build(int[] a, int m) {1630for (int i = 0; i < m; i++) {1631a[i] = 0;1632}16331634for (int i = m; i < a.length; i++) {1635a[i] = 1;1636}1637}1638};16391640abstract void build(int[] a, int m);1641}16421643private static enum UnsortedBuilder {1644RANDOM {1645void build(int[] a, int m, Random random) {1646for (int i = 0; i < a.length; i++) {1647a[i] = random.nextInt();1648}1649}1650},16511652ASCENDING {1653void build(int[] a, int m, Random random) {1654for (int i = 0; i < a.length; i++) {1655a[i] = m + i;1656}1657}1658},16591660DESCENDING {1661void build(int[] a, int m, Random random) {1662for (int i = 0; i < a.length; i++) {1663a[i] = a.length - m - i;1664}1665}1666},16671668EQUAL {1669void build(int[] a, int m, Random random) {1670for (int i = 0; i < a.length; i++) {1671a[i] = m;1672}1673}1674},16751676SAW {1677void build(int[] a, int m, Random random) {1678int incCount = 1;1679int decCount = a.length;1680int i = 0;1681int period = m--;16821683while (true) {1684for (int k = 1; k <= period; k++) {1685if (i >= a.length) {1686return;1687}1688a[i++] = incCount++;1689}1690period += m;16911692for (int k = 1; k <= period; k++) {1693if (i >= a.length) {1694return;1695}1696a[i++] = decCount--;1697}1698period += m;1699}1700}1701},17021703REPEATED {1704void build(int[] a, int m, Random random) {1705for (int i = 0; i < a.length; i++) {1706a[i] = i % m;1707}1708}1709},17101711DUPLICATED {1712void build(int[] a, int m, Random random) {1713for (int i = 0; i < a.length; i++) {1714a[i] = random.nextInt(m);1715}1716}1717},17181719ORGAN_PIPES {1720void build(int[] a, int m, Random random) {1721int middle = a.length / (m + 1);17221723for (int i = 0; i < middle; i++) {1724a[i] = i;1725}17261727for (int i = middle; i < a.length; i++) {1728a[i] = a.length - i - 1;1729}1730}1731},17321733STAGGER {1734void build(int[] a, int m, Random random) {1735for (int i = 0; i < a.length; i++) {1736a[i] = (i * m + i) % a.length;1737}1738}1739},17401741PLATEAU {1742void build(int[] a, int m, Random random) {1743for (int i = 0; i < a.length; i++) {1744a[i] = Math.min(i, m);1745}1746}1747},17481749SHUFFLE {1750void build(int[] a, int m, Random random) {1751int x = 0, y = 0;17521753for (int i = 0; i < a.length; i++) {1754a[i] = random.nextBoolean() ? (x += 2) : (y += 2);1755}1756}1757},17581759LATCH {1760void build(int[] a, int m, Random random) {1761int max = a.length / m;1762max = max < 2 ? 2 : max;17631764for (int i = 0; i < a.length; i++) {1765a[i] = i % max;1766}1767}1768};17691770abstract void build(int[] a, int m, Random random);1771}17721773private static enum MergingBuilder {1774ASCENDING {1775void build(int[] a, int m) {1776int period = a.length / m;1777int v = 1, i = 0;17781779for (int k = 0; k < m; k++) {1780v = 1;17811782for (int p = 0; p < period; p++) {1783a[i++] = v++;1784}1785}17861787for (int j = i; j < a.length - 1; j++) {1788a[j] = v++;1789}17901791a[a.length - 1] = 0;1792}1793},17941795DESCENDING {1796void build(int[] a, int m) {1797int period = a.length / m;1798int v = -1, i = 0;17991800for (int k = 0; k < m; k++) {1801v = -1;18021803for (int p = 0; p < period; p++) {1804a[i++] = v--;1805}1806}18071808for (int j = i; j < a.length - 1; j++) {1809a[j] = v--;1810}18111812a[a.length - 1] = 0;1813}1814},18151816POINT {1817void build(int[] a, int m) {1818for (int i = 0; i < a.length; i++) {1819a[i] = 0;1820}1821a[a.length / 2] = m;1822}1823},18241825LINE {1826void build(int[] a, int m) {1827for (int i = 0; i < a.length; i++) {1828a[i] = i;1829}1830reverse(a, 0, a.length - 1);1831}1832},18331834PEARL {1835void build(int[] a, int m) {1836for (int i = 0; i < a.length; i++) {1837a[i] = i;1838}1839reverse(a, 0, 2);1840}1841},18421843RING {1844void build(int[] a, int m) {1845int k1 = a.length / 3;1846int k2 = a.length / 3 * 2;1847int level = a.length / 3;18481849for (int i = 0, k = level; i < k1; i++) {1850a[i] = k--;1851}18521853for (int i = k1; i < k2; i++) {1854a[i] = 0;1855}18561857for (int i = k2, k = level; i < a.length; i++) {1858a[i] = k--;1859}1860}1861};18621863abstract void build(int[] a, int m);18641865private static void reverse(int[] a, int lo, int hi) {1866for (--hi; lo < hi; ) {1867int tmp = a[lo];1868a[lo++] = a[hi];1869a[hi--] = tmp;1870}1871}1872}18731874private static enum NegativeZeroBuilder {1875FLOAT {1876void build(Object o, Random random) {1877float[] a = (float[]) o;18781879for (int i = 0; i < a.length; i++) {1880a[i] = random.nextBoolean() ? -0.0f : 0.0f;1881}1882}1883},18841885DOUBLE {1886void build(Object o, Random random) {1887double[] a = (double[]) o;18881889for (int i = 0; i < a.length; i++) {1890a[i] = random.nextBoolean() ? -0.0d : 0.0d;1891}1892}1893};18941895abstract void build(Object o, Random random);1896}18971898private static enum FloatingPointBuilder {1899FLOAT {1900void build(Object o, int a, int g, int z, int n, int p, Random random) {1901float negativeValue = -random.nextFloat();1902float positiveValue = random.nextFloat();1903float[] x = (float[]) o;1904int fromIndex = 0;19051906writeValue(x, negativeValue, fromIndex, n);1907fromIndex += n;19081909writeValue(x, -0.0f, fromIndex, g);1910fromIndex += g;19111912writeValue(x, 0.0f, fromIndex, z);1913fromIndex += z;19141915writeValue(x, positiveValue, fromIndex, p);1916fromIndex += p;19171918writeValue(x, Float.NaN, fromIndex, a);1919}1920},19211922DOUBLE {1923void build(Object o, int a, int g, int z, int n, int p, Random random) {1924double negativeValue = -random.nextFloat();1925double positiveValue = random.nextFloat();1926double[] x = (double[]) o;1927int fromIndex = 0;19281929writeValue(x, negativeValue, fromIndex, n);1930fromIndex += n;19311932writeValue(x, -0.0d, fromIndex, g);1933fromIndex += g;19341935writeValue(x, 0.0d, fromIndex, z);1936fromIndex += z;19371938writeValue(x, positiveValue, fromIndex, p);1939fromIndex += p;19401941writeValue(x, Double.NaN, fromIndex, a);1942}1943};19441945abstract void build(Object o, int a, int g, int z, int n, int p, Random random);19461947private static void writeValue(float[] a, float value, int fromIndex, int count) {1948for (int i = fromIndex; i < fromIndex + count; i++) {1949a[i] = value;1950}1951}19521953private static void writeValue(double[] a, double value, int fromIndex, int count) {1954for (int i = fromIndex; i < fromIndex + count; i++) {1955a[i] = value;1956}1957}1958}19591960private static Comparator<Pair> pairComparator = new Comparator<Pair>() {19611962@Override1963public int compare(Pair p1, Pair p2) {1964return p1.compareTo(p2);1965}1966};19671968private static class Pair implements Comparable<Pair> {19691970private Pair(int key, int value) {1971this.key = key;1972this.value = value;1973}19741975int getKey() {1976return key;1977}19781979int getValue() {1980return value;1981}19821983@Override1984public int compareTo(Pair pair) {1985return Integer.compare(key, pair.key);1986}19871988@Override1989public String toString() {1990return "(" + key + ", " + value + ")";1991}19921993private int key;1994private int value;1995}19961997private static class TestRandom extends Random {19981999private static final TestRandom BABA = new TestRandom(0xBABA);2000private static final TestRandom DEDA = new TestRandom(0xDEDA);2001private static final TestRandom C0FFEE = new TestRandom(0xC0FFEE);20022003private TestRandom(long seed) {2004super(seed);2005this.seed = Long.toHexString(seed).toUpperCase();2006}20072008@Override2009public String toString() {2010return seed;2011}20122013private String seed;2014}2015}201620172018