1 /*
2  * Copyright (c) 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package test.java.util.Arrays;
27 
28 import java.lang.invoke.MethodHandle;
29 import java.lang.invoke.MethodHandles;
30 import java.lang.reflect.Method;
31 import java.util.*;
32 
33 /**
34  * This class provides access to package-private
35  * methods of DualPivotQuicksort class.
36  *
37  * @author Vladimir Yaroslavskiy
38  *
39  * @version 2019.09.19
40  *
41  * @since 14
42  */
43 public enum SortingHelper {
44 
45     DUAL_PIVOT_QUICKSORT("Dual-Pivot Quicksort") {
46 
47         @Override
sort(Object a)48         public void sort(Object a) {
49             // BEGIN Android-changed: we can't place this class in java.util,
50             // using reflection to get these methods.
51             /*
52             if (a instanceof int[]) {
53                 DualPivotQuicksort.sort((int[]) a, SEQUENTIAL, 0, ((int[]) a).length);
54             } else if (a instanceof long[]) {
55                 DualPivotQuicksort.sort((long[]) a, SEQUENTIAL, 0, ((long[]) a).length);
56             } else if (a instanceof byte[]) {
57                 DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
58             } else if (a instanceof char[]) {
59                 DualPivotQuicksort.sort((char[]) a, SEQUENTIAL, 0, ((char[]) a).length);
60             } else if (a instanceof short[]) {
61                 DualPivotQuicksort.sort((short[]) a, SEQUENTIAL, 0, ((short[]) a).length);
62             } else if (a instanceof float[]) {
63                 DualPivotQuicksort.sort((float[]) a, SEQUENTIAL, 0, ((float[]) a).length);
64             } else if (a instanceof double[]) {
65                 DualPivotQuicksort.sort((double[]) a, SEQUENTIAL, 0, ((double[]) a).length);
66             } else {
67                 fail(a);
68             }
69             */
70             try {
71                 if (a instanceof int[]) {
72                     MethodHandleHolder.INT_SORT.invoke(
73                             (int[]) a, SEQUENTIAL, 0, ((int[]) a).length);
74                 } else if (a instanceof long[]) {
75                     MethodHandleHolder.LONG_SORT.invoke(
76                             (long[]) a, SEQUENTIAL, 0, ((long[]) a).length);
77                 } else if (a instanceof byte[]) {
78                     MethodHandleHolder.BYTE_SORT.invoke(
79                             (byte[]) a, 0, ((byte[]) a).length);
80                 } else if (a instanceof char[]) {
81                     MethodHandleHolder.CHAR_SORT.invoke(
82                             (char[]) a, SEQUENTIAL, 0, ((char[]) a).length);
83                 } else if (a instanceof short[]) {
84                     MethodHandleHolder.SHORT_SORT.invoke(
85                             (short[]) a, SEQUENTIAL, 0, ((short[]) a).length);
86                 } else if (a instanceof float[]) {
87                     MethodHandleHolder.FLOAT_SORT.invoke(
88                             (float[]) a, SEQUENTIAL, 0, ((float[]) a).length);
89                 } else if (a instanceof double[]) {
90                     MethodHandleHolder.DOUBLE_SORT.invoke(
91                             (double[]) a, SEQUENTIAL, 0, ((double[]) a).length);
92                 } else {
93                     fail(a);
94                 }
95             } catch (RuntimeException re) {
96                 // propagate RuntimeException as it is.
97                 throw re;
98             } catch (Throwable e) {
99                 throw new AssertionError(e);
100             }
101             // END Android-changed: we can't place this class in java.util,
102             // using reflection to get these methods.
103         }
104 
105         @Override
sort(Object a, int low, int high)106         public void sort(Object a, int low, int high) {
107             // BEGIN Android-changed: we can't place this class in java.util,
108             // using reflection to get these methods.
109             /*
110             if (a instanceof int[]) {
111                 DualPivotQuicksort.sort((int[]) a, SEQUENTIAL, low, high);
112             } else if (a instanceof long[]) {
113                 DualPivotQuicksort.sort((long[]) a, SEQUENTIAL, low, high);
114             } else if (a instanceof byte[]) {
115                 DualPivotQuicksort.sort((byte[]) a, low, high);
116             } else if (a instanceof char[]) {
117                 DualPivotQuicksort.sort((char[]) a, SEQUENTIAL, low, high);
118             } else if (a instanceof short[]) {
119                 DualPivotQuicksort.sort((short[]) a, SEQUENTIAL, low, high);
120             } else if (a instanceof float[]) {
121                 DualPivotQuicksort.sort((float[]) a, SEQUENTIAL, low, high);
122             } else if (a instanceof double[]) {
123                 DualPivotQuicksort.sort((double[]) a, SEQUENTIAL, low, high);
124             } else {
125                 fail(a);
126             }
127             */
128             try {
129                 if (a instanceof int[]) {
130                     MethodHandleHolder.INT_SORT.invoke(
131                             (int[]) a, SEQUENTIAL, low, high);
132                 } else if (a instanceof long[]) {
133                     MethodHandleHolder.LONG_SORT.invoke(
134                             (long[]) a, SEQUENTIAL, low, high);
135                 } else if (a instanceof byte[]) {
136                     MethodHandleHolder.BYTE_SORT.invoke(
137                             (byte[]) a, low, high);
138                 } else if (a instanceof char[]) {
139                     MethodHandleHolder.CHAR_SORT.invoke(
140                             (char[]) a, SEQUENTIAL, low, high);
141                 } else if (a instanceof short[]) {
142                     MethodHandleHolder.SHORT_SORT.invoke(
143                             (short[]) a, SEQUENTIAL, low, high);
144                 } else if (a instanceof float[]) {
145                     MethodHandleHolder.FLOAT_SORT.invoke(
146                             (float[]) a, SEQUENTIAL, low, high);
147                 } else if (a instanceof double[]) {
148                     MethodHandleHolder.DOUBLE_SORT.invoke(
149                             (double[]) a, SEQUENTIAL, low, high);
150                 } else {
151                     fail(a);
152                 }
153             } catch (RuntimeException re) {
154                 // propagate RuntimeException as it is.
155                 throw re;
156             } catch (Throwable e) {
157                 throw new AssertionError(e);
158             }
159             // END Android-changed: we can't place this class in java.util,
160             // using reflection to get these methods.
161         }
162 
163         @Override
sort(Object[] a)164         public void sort(Object[] a) {
165             fail(a);
166         }
167 
168         @Override
sort(Object[] a, Comparator comparator)169         public void sort(Object[] a, Comparator comparator) {
170             fail(a);
171         }
172     },
173 
174     PARALLEL_SORT("Parallel sort") {
175 
176         @Override
sort(Object a)177         public void sort(Object a) {
178             // BEGIN Android-changed: we can't place this class in java.util,
179             // using reflection to get these methods.
180             /*
181             if (a instanceof int[]) {
182                 DualPivotQuicksort.sort((int[]) a, PARALLEL, 0, ((int[]) a).length);
183             } else if (a instanceof long[]) {
184                 DualPivotQuicksort.sort((long[]) a, PARALLEL, 0, ((long[]) a).length);
185             } else if (a instanceof byte[]) {
186                 DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
187             } else if (a instanceof char[]) {
188                 DualPivotQuicksort.sort((char[]) a, PARALLEL, 0, ((char[]) a).length);
189             } else if (a instanceof short[]) {
190                 DualPivotQuicksort.sort((short[]) a, PARALLEL, 0, ((short[]) a).length);
191             } else if (a instanceof float[]) {
192                 DualPivotQuicksort.sort((float[]) a, PARALLEL, 0, ((float[]) a).length);
193             } else if (a instanceof double[]) {
194                 DualPivotQuicksort.sort((double[]) a, PARALLEL, 0, ((double[]) a).length);
195             } else {
196                 fail(a);
197             }
198             */
199             try {
200                 if (a instanceof int[]) {
201                     MethodHandleHolder.INT_SORT.invoke(
202                             (int[]) a, PARALLEL, 0, ((int[]) a).length);
203                 } else if (a instanceof long[]) {
204                     MethodHandleHolder.LONG_SORT.invoke(
205                             (long[]) a, PARALLEL, 0, ((long[]) a).length);
206                 } else if (a instanceof byte[]) {
207                     MethodHandleHolder.BYTE_SORT.invoke(
208                             (byte[]) a, 0, ((byte[]) a).length);
209                 } else if (a instanceof char[]) {
210                     MethodHandleHolder.CHAR_SORT.invoke(
211                             (char[]) a, PARALLEL, 0, ((char[]) a).length);
212                 } else if (a instanceof short[]) {
213                     MethodHandleHolder.SHORT_SORT.invoke(
214                             (short[]) a, PARALLEL, 0, ((short[]) a).length);
215                 } else if (a instanceof float[]) {
216                     MethodHandleHolder.FLOAT_SORT.invoke(
217                             (float[]) a, PARALLEL, 0, ((float[]) a).length);
218                 } else if (a instanceof double[]) {
219                     MethodHandleHolder.DOUBLE_SORT.invoke(
220                             (double[]) a, PARALLEL, 0, ((double[]) a).length);
221                 } else {
222                     fail(a);
223                 }
224             } catch (RuntimeException re) {
225                 // propagate RuntimeException as it is.
226                 throw re;
227             } catch (Throwable e) {
228                 throw new AssertionError(e);
229             }
230             // END Android-changed: we can't place this class in java.util,
231             // using reflection to get these methods.
232         }
233 
234         @Override
sort(Object a, int low, int high)235         public void sort(Object a, int low, int high) {
236             // BEGIN Android-changed: we can't place this class in java.util,
237             // using reflection to get these methods.
238             /*
239             if (a instanceof int[]) {
240                 DualPivotQuicksort.sort((int[]) a, PARALLEL, low, high);
241             } else if (a instanceof long[]) {
242                 DualPivotQuicksort.sort((long[]) a, PARALLEL, low, high);
243             } else if (a instanceof byte[]) {
244                 DualPivotQuicksort.sort((byte[]) a, low, high);
245             } else if (a instanceof char[]) {
246                 DualPivotQuicksort.sort((char[]) a, PARALLEL, low, high);
247             } else if (a instanceof short[]) {
248                 DualPivotQuicksort.sort((short[]) a, PARALLEL, low, high);
249             } else if (a instanceof float[]) {
250                 DualPivotQuicksort.sort((float[]) a, PARALLEL, low, high);
251             } else if (a instanceof double[]) {
252                 DualPivotQuicksort.sort((double[]) a, PARALLEL, low, high);
253             } else {
254                 fail(a);
255             }
256             */
257             try {
258                 if (a instanceof int[]) {
259                     MethodHandleHolder.INT_SORT.invoke(
260                             (int[]) a, PARALLEL, low, high);
261                 } else if (a instanceof long[]) {
262                     MethodHandleHolder.LONG_SORT.invoke(
263                             (long[]) a, PARALLEL, low, high);
264                 } else if (a instanceof byte[]) {
265                     MethodHandleHolder.BYTE_SORT.invoke(
266                             (byte[]) a, low, high);
267                 } else if (a instanceof char[]) {
268                     MethodHandleHolder.CHAR_SORT.invoke(
269                             (char[]) a, PARALLEL, low, high);
270                 } else if (a instanceof short[]) {
271                     MethodHandleHolder.SHORT_SORT.invoke(
272                             (short[]) a, PARALLEL, low, high);
273                 } else if (a instanceof float[]) {
274                     MethodHandleHolder.FLOAT_SORT.invoke(
275                             (float[]) a, PARALLEL, low, high);
276                 } else if (a instanceof double[]) {
277                     MethodHandleHolder.DOUBLE_SORT.invoke(
278                             (double[]) a, PARALLEL, low, high);
279                 } else {
280                     fail(a);
281                 }
282             } catch (RuntimeException re) {
283                 // propagate RuntimeException as it is.
284                 throw re;
285             } catch (Throwable e) {
286                 throw new AssertionError(e);
287             }
288             // END Android-changed: we can't place this class in java.util,
289             // using reflection to get these methods.
290         }
291 
292         @Override
sort(Object[] a)293         public void sort(Object[] a) {
294             fail(a);
295         }
296 
297         @Override
sort(Object[] a, Comparator comparator)298         public void sort(Object[] a, Comparator comparator) {
299             fail(a);
300         }
301     },
302 
303     HEAP_SORT("Heap sort") {
304 
305         @Override
sort(Object a)306         public void sort(Object a) {
307             // BEGIN Android-changed: we can't place this class in java.util,
308             // using reflection to get these methods.
309             /*
310             if (a instanceof int[]) {
311                 DualPivotQuicksort.sort(null, (int[]) a, BIG_DEPTH, 0, ((int[]) a).length);
312             } else if (a instanceof long[]) {
313                 DualPivotQuicksort.sort(null, (long[]) a, BIG_DEPTH, 0, ((long[]) a).length);
314             } else if (a instanceof byte[]) {
315                 DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
316             } else if (a instanceof char[]) {
317                 DualPivotQuicksort.sort((char[]) a, BIG_DEPTH, 0, ((char[]) a).length);
318             } else if (a instanceof short[]) {
319                 DualPivotQuicksort.sort((short[]) a, BIG_DEPTH, 0, ((short[]) a).length);
320             } else if (a instanceof float[]) {
321                 DualPivotQuicksort.sort(null, (float[]) a, BIG_DEPTH, 0, ((float[]) a).length);
322             } else if (a instanceof double[]) {
323                 DualPivotQuicksort.sort(null, (double[]) a, BIG_DEPTH, 0, ((double[]) a).length);
324             } else {
325                 fail(a);
326             }
327             */
328             try {
329                 if (a instanceof int[]) {
330                     MethodHandleHolder.INT_SORTER_SORT.invoke(
331                             null, (int[]) a, BIG_DEPTH, 0, ((int[]) a).length);
332                 } else if (a instanceof long[]) {
333                     MethodHandleHolder.LONG_SORTER_SORT.invoke(
334                             null, (long[]) a, BIG_DEPTH, 0, ((long[]) a).length);
335                 } else if (a instanceof byte[]) {
336                     MethodHandleHolder.BYTE_SORT.invoke(
337                             (byte[]) a, 0, ((byte[]) a).length);
338                 } else if (a instanceof char[]) {
339                     MethodHandleHolder.CHAR_SORT.invoke(
340                             (char[]) a, BIG_DEPTH, 0, ((char[]) a).length);
341                 } else if (a instanceof short[]) {
342                     MethodHandleHolder.SHORT_SORT.invoke(
343                             (short[]) a, BIG_DEPTH, 0, ((short[]) a).length);
344                 } else if (a instanceof float[]) {
345                     MethodHandleHolder.FLOAT_SORTER_SORT.invoke(
346                             null, (float[]) a, BIG_DEPTH, 0, ((float[]) a).length);
347                 } else if (a instanceof double[]) {
348                     MethodHandleHolder.DOUBLE_SORTER_SORT.invoke(
349                             null, (double[]) a, BIG_DEPTH, 0, ((double[]) a).length);
350                 } else {
351                     fail(a);
352                 }
353             } catch (RuntimeException re) {
354                 // propagate RuntimeException as it is.
355                 throw re;
356             } catch (Throwable e) {
357                 throw new AssertionError(e);
358             }
359             // END Android-changed: we can't place this class in java.util,
360             // using reflection to get these methods.
361         }
362 
363         @Override
sort(Object a, int low, int high)364         public void sort(Object a, int low, int high) {
365             // BEGIN Android-changed: we can't place this class in java.util,
366             // using reflection to get these methods.
367             /*
368             if (a instanceof int[]) {
369                 DualPivotQuicksort.sort(null, (int[]) a, BIG_DEPTH, low, high);
370             } else if (a instanceof long[]) {
371                 DualPivotQuicksort.sort(null, (long[]) a, BIG_DEPTH, low, high);
372             } else if (a instanceof byte[]) {
373                 DualPivotQuicksort.sort((byte[]) a, low, high);
374             } else if (a instanceof char[]) {
375                 DualPivotQuicksort.sort((char[]) a, BIG_DEPTH, low, high);
376             } else if (a instanceof short[]) {
377                 DualPivotQuicksort.sort((short[]) a, BIG_DEPTH, low, high);
378             } else if (a instanceof float[]) {
379                 DualPivotQuicksort.sort(null, (float[]) a, BIG_DEPTH, low, high);
380             } else if (a instanceof double[]) {
381                 DualPivotQuicksort.sort(null, (double[]) a, BIG_DEPTH, low, high);
382             } else {
383                 fail(a);
384             }
385 
386             */
387             try {
388                 if (a instanceof int[]) {
389                     MethodHandleHolder.INT_SORTER_SORT.invoke(
390                             null, (int[]) a, BIG_DEPTH, low, high);
391                 } else if (a instanceof long[]) {
392                     MethodHandleHolder.LONG_SORTER_SORT.invoke(
393                             null, (long[]) a, BIG_DEPTH, low, high);
394                 } else if (a instanceof byte[]) {
395                     MethodHandleHolder.BYTE_SORT.invoke((byte[]) a, low, high);
396                 } else if (a instanceof char[]) {
397                     MethodHandleHolder.CHAR_SORT.invoke(
398                             (char[]) a, BIG_DEPTH, low, high);
399                 } else if (a instanceof short[]) {
400                     MethodHandleHolder.SHORT_SORT.invoke(
401                             (short[]) a, BIG_DEPTH, low, high);
402                 } else if (a instanceof float[]) {
403                     MethodHandleHolder.FLOAT_SORTER_SORT.invoke(
404                             null, (float[]) a, BIG_DEPTH, low, high);
405                 } else if (a instanceof double[]) {
406                     MethodHandleHolder.DOUBLE_SORTER_SORT.invoke(
407                             null, (double[]) a, BIG_DEPTH, low, high);
408                 } else {
409                     fail(a);
410                 }
411             } catch (RuntimeException re) {
412                 // propagate RuntimeException as it is.
413                 throw re;
414             } catch (Throwable e) {
415                 throw new AssertionError(e);
416             }
417             // END Android-changed: we can't place this class in java.util,
418             // using reflection to get these methods.
419         }
420 
421         @Override
sort(Object[] a)422         public void sort(Object[] a) {
423             fail(a);
424         }
425 
426         @Override
sort(Object[] a, Comparator comparator)427         public void sort(Object[] a, Comparator comparator) {
428             fail(a);
429         }
430     },
431 
432     ARRAYS_SORT("Arrays.sort") {
433 
434         @Override
sort(Object a)435         public void sort(Object a) {
436             if (a instanceof int[]) {
437                 Arrays.sort((int[]) a);
438             } else if (a instanceof long[]) {
439                 Arrays.sort((long[]) a);
440             } else if (a instanceof byte[]) {
441                 Arrays.sort((byte[]) a);
442             } else if (a instanceof char[]) {
443                 Arrays.sort((char[]) a);
444             } else if (a instanceof short[]) {
445                 Arrays.sort((short[]) a);
446             } else if (a instanceof float[]) {
447                 Arrays.sort((float[]) a);
448             } else if (a instanceof double[]) {
449                 Arrays.sort((double[]) a);
450             } else {
451                 fail(a);
452             }
453         }
454 
455         @Override
sort(Object a, int low, int high)456         public void sort(Object a, int low, int high) {
457             if (a instanceof int[]) {
458                 Arrays.sort((int[]) a, low, high);
459             } else if (a instanceof long[]) {
460                 Arrays.sort((long[]) a, low, high);
461             } else if (a instanceof byte[]) {
462                 Arrays.sort((byte[]) a, low, high);
463             } else if (a instanceof char[]) {
464                 Arrays.sort((char[]) a, low, high);
465             } else if (a instanceof short[]) {
466                 Arrays.sort((short[]) a, low, high);
467             } else if (a instanceof float[]) {
468                 Arrays.sort((float[]) a, low, high);
469             } else if (a instanceof double[]) {
470                 Arrays.sort((double[]) a, low, high);
471             } else {
472                 fail(a);
473             }
474         }
475 
476         @Override
sort(Object[] a)477         public void sort(Object[] a) {
478             Arrays.sort(a);
479         }
480 
481         @Override
482         @SuppressWarnings("unchecked")
sort(Object[] a, Comparator comparator)483         public void sort(Object[] a, Comparator comparator) {
484             Arrays.sort(a, comparator);
485         }
486     },
487 
488     ARRAYS_PARALLEL_SORT("Arrays.parallelSort") {
489 
490         @Override
sort(Object a)491         public void sort(Object a) {
492             if (a instanceof int[]) {
493                 Arrays.parallelSort((int[]) a);
494             } else if (a instanceof long[]) {
495                 Arrays.parallelSort((long[]) a);
496             } else if (a instanceof byte[]) {
497                 Arrays.parallelSort((byte[]) a);
498             } else if (a instanceof char[]) {
499                 Arrays.parallelSort((char[]) a);
500             } else if (a instanceof short[]) {
501                 Arrays.parallelSort((short[]) a);
502             } else if (a instanceof float[]) {
503                 Arrays.parallelSort((float[]) a);
504             } else if (a instanceof double[]) {
505                 Arrays.parallelSort((double[]) a);
506             } else {
507                 fail(a);
508             }
509         }
510 
511         @Override
sort(Object a, int low, int high)512         public void sort(Object a, int low, int high) {
513             if (a instanceof int[]) {
514                 Arrays.parallelSort((int[]) a, low, high);
515             } else if (a instanceof long[]) {
516                 Arrays.parallelSort((long[]) a, low, high);
517             } else if (a instanceof byte[]) {
518                 Arrays.parallelSort((byte[]) a, low, high);
519             } else if (a instanceof char[]) {
520                 Arrays.parallelSort((char[]) a, low, high);
521             } else if (a instanceof short[]) {
522                 Arrays.parallelSort((short[]) a, low, high);
523             } else if (a instanceof float[]) {
524                 Arrays.parallelSort((float[]) a, low, high);
525             } else if (a instanceof double[]) {
526                 Arrays.parallelSort((double[]) a, low, high);
527             } else {
528                 fail(a);
529             }
530         }
531 
532         @Override
533         @SuppressWarnings("unchecked")
sort(Object[] a)534         public void sort(Object[] a) {
535             Arrays.parallelSort((Comparable[]) a);
536         }
537 
538         @Override
539         @SuppressWarnings("unchecked")
sort(Object[] a, Comparator comparator)540         public void sort(Object[] a, Comparator comparator) {
541             Arrays.parallelSort(a, comparator);
542         }
543     };
544 
sort(Object a)545     abstract public void sort(Object a);
546 
sort(Object a, int low, int high)547     abstract public void sort(Object a, int low, int high);
548 
sort(Object[] a)549     abstract public void sort(Object[] a);
550 
sort(Object[] a, Comparator comparator)551     abstract public void sort(Object[] a, Comparator comparator);
552 
SortingHelper(String name)553     private SortingHelper(String name) {
554         this.name = name;
555     }
556 
557     @Override
toString()558     public String toString() {
559         return name;
560     }
561 
fail(Object a)562     private static void fail(Object a) {
563         throw new RuntimeException("Unexpected type of array: " + a.getClass().getName());
564     }
565 
566     private String name;
567 
568     /**
569      * Parallelism level for sequential and parallel sorting.
570      */
571     private static final int SEQUENTIAL = 0;
572     private static final int PARALLEL = 87;
573 
574     /**
575      * Heap sort will be invoked, if recursion depth is too big.
576      * Value is taken from DualPivotQuicksort.MAX_RECURSION_DEPTH.
577      */
578     private static final int BIG_DEPTH = 64 * (3 << 1);
579 }
580 
581 // BEGIN Android-added: we can't place this class in java.util,
582 // using reflection to get these methods.
583 class MethodHandleHolder {
584     public static final MethodHandle INT_SORT;
585     public static final MethodHandle LONG_SORT;
586     public static final MethodHandle BYTE_SORT;
587     public static final MethodHandle CHAR_SORT;
588     public static final MethodHandle SHORT_SORT;
589     public static final MethodHandle FLOAT_SORT;
590     public static final MethodHandle DOUBLE_SORT;
591 
592     public static final MethodHandle INT_SORTER_SORT;
593     public static final MethodHandle LONG_SORTER_SORT;
594     public static final MethodHandle FLOAT_SORTER_SORT;
595     public static final MethodHandle DOUBLE_SORTER_SORT;
596 
597 
598     static {
599         try {
600             INT_SORT = makeAccessibleAndUnreflect(
601                     Class.forName("java.util.DualPivotQuicksort")
602                             .getDeclaredMethod(
603                                     "sort", int[].class, int.class, int.class, int.class));
604             LONG_SORT = makeAccessibleAndUnreflect(
605                     Class.forName("java.util.DualPivotQuicksort")
606                             .getDeclaredMethod(
607                                     "sort", long[].class, int.class, int.class, int.class));
608             BYTE_SORT = makeAccessibleAndUnreflect(
609                     Class.forName("java.util.DualPivotQuicksort")
610                             .getDeclaredMethod(
611                                     "sort", byte[].class, int.class, int.class));
612             CHAR_SORT = makeAccessibleAndUnreflect(
613                     Class.forName("java.util.DualPivotQuicksort")
614                             .getDeclaredMethod(
615                                     "sort", char[].class, int.class, int.class, int.class));
616             SHORT_SORT = makeAccessibleAndUnreflect(
617                     Class.forName("java.util.DualPivotQuicksort")
618                             .getDeclaredMethod(
619                                     "sort", short[].class, int.class, int.class, int.class));
620             FLOAT_SORT = makeAccessibleAndUnreflect(
621                     Class.forName("java.util.DualPivotQuicksort")
622                             .getDeclaredMethod(
623                                     "sort", float[].class, int.class, int.class, int.class));
624             DOUBLE_SORT = makeAccessibleAndUnreflect(
625                     Class.forName("java.util.DualPivotQuicksort")
626                             .getDeclaredMethod(
627                                     "sort", double[].class, int.class, int.class, int.class));
628 
629             Class<?> sorterClass = Class.forName("java.util.DualPivotQuicksort$Sorter");
630             INT_SORTER_SORT = makeAccessibleAndUnreflect(
631                     Class.forName("java.util.DualPivotQuicksort")
632                             .getDeclaredMethod("sort", sorterClass,
633                                     int[].class, int.class, int.class, int.class));
634             LONG_SORTER_SORT = makeAccessibleAndUnreflect(
635                     Class.forName("java.util.DualPivotQuicksort")
636                             .getDeclaredMethod("sort", sorterClass,
637                                     long[].class, int.class, int.class, int.class));
638             FLOAT_SORTER_SORT = makeAccessibleAndUnreflect(
639                     Class.forName("java.util.DualPivotQuicksort")
640                             .getDeclaredMethod("sort", sorterClass,
641                                     float[].class, int.class, int.class, int.class));
642             DOUBLE_SORTER_SORT = makeAccessibleAndUnreflect(
643                     Class.forName("java.util.DualPivotQuicksort")
644                             .getDeclaredMethod("sort", sorterClass,
645                                     double[].class, int.class, int.class, int.class));
646         } catch (Exception e) {
647             throw new AssertionError(e);
648         }
649     }
650 
makeAccessibleAndUnreflect(Method method)651     private static MethodHandle makeAccessibleAndUnreflect(Method method)
652             throws IllegalAccessException {
653         method.setAccessible(true);
654         return MethodHandles.lookup().unreflect(method);
655     }
656 }
657 // END Android-changed: we can't place this class in java.util,
658 // using reflection to get these methods.