mirror of
https://github.com/darlinghq/darling-openjdk.git
synced 2024-11-30 15:50:29 +00:00
8226297: Dual-pivot quicksort improvements
Reviewed-by: dl, lbourges
This commit is contained in:
parent
7dafe378d3
commit
de54eb1513
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,6 @@
|
||||
*/
|
||||
package java.util;
|
||||
|
||||
import java.util.concurrent.RecursiveAction;
|
||||
import java.util.concurrent.CountedCompleter;
|
||||
|
||||
/**
|
||||
@ -36,7 +35,7 @@ import java.util.concurrent.CountedCompleter;
|
||||
* Sorter classes based mainly on CilkSort
|
||||
* <A href="http://supertech.lcs.mit.edu/cilk/"> Cilk</A>:
|
||||
* Basic algorithm:
|
||||
* if array size is small, just use a sequential quicksort (via Arrays.sort)
|
||||
* if array size is small, just use a sequential sort (via Arrays.sort)
|
||||
* Otherwise:
|
||||
* 1. Break array in half.
|
||||
* 2. For each half,
|
||||
@ -63,14 +62,10 @@ import java.util.concurrent.CountedCompleter;
|
||||
* need to keep track of the arrays, and are never themselves forked,
|
||||
* so don't hold any task state.
|
||||
*
|
||||
* The primitive class versions (FJByte... FJDouble) are
|
||||
* identical to each other except for type declarations.
|
||||
*
|
||||
* The base sequential sorts rely on non-public versions of TimSort,
|
||||
* ComparableTimSort, and DualPivotQuicksort sort methods that accept
|
||||
* temp workspace array slices that we will have already allocated, so
|
||||
* avoids redundant allocation. (Except for DualPivotQuicksort byte[]
|
||||
* sort, that does not ever use a workspace array.)
|
||||
* ComparableTimSort sort methods that accept temp workspace array
|
||||
* slices that we will have already allocated, so avoids redundant
|
||||
* allocation.
|
||||
*/
|
||||
/*package*/ class ArraysParallelSortHelpers {
|
||||
|
||||
@ -142,7 +137,7 @@ import java.util.concurrent.CountedCompleter;
|
||||
Relay rc = new Relay(new Merger<>(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g, c));
|
||||
new Sorter<>(rc, a, w, b+u, n-u, wb+u, g, c).fork();
|
||||
new Sorter<>(rc, a, w, b+h, q, wb+h, g, c).fork();;
|
||||
new Sorter<>(rc, a, w, b+h, q, wb+h, g, c).fork();
|
||||
Relay bc = new Relay(new Merger<>(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g, c));
|
||||
new Sorter<>(bc, a, w, b+q, h-q, wb+q, g, c).fork();
|
||||
@ -239,799 +234,6 @@ import java.util.concurrent.CountedCompleter;
|
||||
|
||||
tryComplete();
|
||||
}
|
||||
|
||||
}
|
||||
} // FJObject
|
||||
|
||||
/** byte support class */
|
||||
static final class FJByte {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final byte[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, byte[] a, byte[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
byte[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final byte[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, byte[] a, byte[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
byte[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
byte split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
byte split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
byte t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJByte
|
||||
|
||||
/** char support class */
|
||||
static final class FJChar {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final char[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, char[] a, char[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
char[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final char[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, char[] a, char[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
char[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
char split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
char split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
char t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJChar
|
||||
|
||||
/** short support class */
|
||||
static final class FJShort {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final short[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, short[] a, short[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
short[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final short[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, short[] a, short[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
short[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
short split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
short split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
short t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJShort
|
||||
|
||||
/** int support class */
|
||||
static final class FJInt {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final int[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, int[] a, int[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
int[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final int[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, int[] a, int[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
int[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
int split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
int split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
int t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJInt
|
||||
|
||||
/** long support class */
|
||||
static final class FJLong {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final long[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, long[] a, long[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
long[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final long[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, long[] a, long[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
long[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
long split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
long split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
long t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJLong
|
||||
|
||||
/** float support class */
|
||||
static final class FJFloat {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final float[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, float[] a, float[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
float[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final float[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, float[] a, float[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
float[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
float split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
float split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
float t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJFloat
|
||||
|
||||
/** double support class */
|
||||
static final class FJDouble {
|
||||
static final class Sorter extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final double[] a, w;
|
||||
final int base, size, wbase, gran;
|
||||
Sorter(CountedCompleter<?> par, double[] a, double[] w, int base,
|
||||
int size, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w; this.base = base; this.size = size;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
public final void compute() {
|
||||
CountedCompleter<?> s = this;
|
||||
double[] a = this.a, w = this.w; // localize all params
|
||||
int b = this.base, n = this.size, wb = this.wbase, g = this.gran;
|
||||
while (n > g) {
|
||||
int h = n >>> 1, q = h >>> 1, u = h + q; // quartiles
|
||||
Relay fc = new Relay(new Merger(s, w, a, wb, h,
|
||||
wb+h, n-h, b, g));
|
||||
Relay rc = new Relay(new Merger(fc, a, w, b+h, q,
|
||||
b+u, n-u, wb+h, g));
|
||||
new Sorter(rc, a, w, b+u, n-u, wb+u, g).fork();
|
||||
new Sorter(rc, a, w, b+h, q, wb+h, g).fork();;
|
||||
Relay bc = new Relay(new Merger(fc, a, w, b, q,
|
||||
b+q, h-q, wb, g));
|
||||
new Sorter(bc, a, w, b+q, h-q, wb+q, g).fork();
|
||||
s = new EmptyCompleter(bc);
|
||||
n = q;
|
||||
}
|
||||
DualPivotQuicksort.sort(a, b, b + n - 1, w, wb, n);
|
||||
s.tryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
static final class Merger extends CountedCompleter<Void> {
|
||||
@java.io.Serial
|
||||
static final long serialVersionUID = 2446542900576103244L;
|
||||
final double[] a, w; // main and workspace arrays
|
||||
final int lbase, lsize, rbase, rsize, wbase, gran;
|
||||
Merger(CountedCompleter<?> par, double[] a, double[] w,
|
||||
int lbase, int lsize, int rbase,
|
||||
int rsize, int wbase, int gran) {
|
||||
super(par);
|
||||
this.a = a; this.w = w;
|
||||
this.lbase = lbase; this.lsize = lsize;
|
||||
this.rbase = rbase; this.rsize = rsize;
|
||||
this.wbase = wbase; this.gran = gran;
|
||||
}
|
||||
|
||||
public final void compute() {
|
||||
double[] a = this.a, w = this.w; // localize all params
|
||||
int lb = this.lbase, ln = this.lsize, rb = this.rbase,
|
||||
rn = this.rsize, k = this.wbase, g = this.gran;
|
||||
if (a == null || w == null || lb < 0 || rb < 0 || k < 0)
|
||||
throw new IllegalStateException(); // hoist checks
|
||||
for (int lh, rh;;) { // split larger, find point in smaller
|
||||
if (ln >= rn) {
|
||||
if (ln <= g)
|
||||
break;
|
||||
rh = rn;
|
||||
double split = a[(lh = ln >>> 1) + lb];
|
||||
for (int lo = 0; lo < rh; ) {
|
||||
int rm = (lo + rh) >>> 1;
|
||||
if (split <= a[rm + rb])
|
||||
rh = rm;
|
||||
else
|
||||
lo = rm + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rn <= g)
|
||||
break;
|
||||
lh = ln;
|
||||
double split = a[(rh = rn >>> 1) + rb];
|
||||
for (int lo = 0; lo < lh; ) {
|
||||
int lm = (lo + lh) >>> 1;
|
||||
if (split <= a[lm + lb])
|
||||
lh = lm;
|
||||
else
|
||||
lo = lm + 1;
|
||||
}
|
||||
}
|
||||
Merger m = new Merger(this, a, w, lb + lh, ln - lh,
|
||||
rb + rh, rn - rh,
|
||||
k + lh + rh, g);
|
||||
rn = rh;
|
||||
ln = lh;
|
||||
addToPendingCount(1);
|
||||
m.fork();
|
||||
}
|
||||
|
||||
int lf = lb + ln, rf = rb + rn; // index bounds
|
||||
while (lb < lf && rb < rf) {
|
||||
double t, al, ar;
|
||||
if ((al = a[lb]) <= (ar = a[rb])) {
|
||||
lb++; t = al;
|
||||
}
|
||||
else {
|
||||
rb++; t = ar;
|
||||
}
|
||||
w[k++] = t;
|
||||
}
|
||||
if (rb < rf)
|
||||
System.arraycopy(a, rb, w, k, rf - rb);
|
||||
else if (lb < lf)
|
||||
System.arraycopy(a, lb, w, k, lf - lb);
|
||||
tryComplete();
|
||||
}
|
||||
}
|
||||
} // FJDouble
|
||||
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
352
test/jdk/java/util/Arrays/java.base/java/util/SortingHelper.java
Normal file
352
test/jdk/java/util/Arrays/java.base/java/util/SortingHelper.java
Normal file
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.util;
|
||||
|
||||
/**
|
||||
* This class provides access to package-private
|
||||
* methods of DualPivotQuicksort class.
|
||||
*
|
||||
* @author Vladimir Yaroslavskiy
|
||||
*
|
||||
* @version 2019.09.19
|
||||
*
|
||||
* @since 14
|
||||
*/
|
||||
public enum SortingHelper {
|
||||
|
||||
DUAL_PIVOT_QUICKSORT("Dual-Pivot Quicksort") {
|
||||
|
||||
@Override
|
||||
public void sort(Object a) {
|
||||
if (a instanceof int[]) {
|
||||
DualPivotQuicksort.sort((int[]) a, SEQUENTIAL, 0, ((int[]) a).length);
|
||||
} else if (a instanceof long[]) {
|
||||
DualPivotQuicksort.sort((long[]) a, SEQUENTIAL, 0, ((long[]) a).length);
|
||||
} else if (a instanceof byte[]) {
|
||||
DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
|
||||
} else if (a instanceof char[]) {
|
||||
DualPivotQuicksort.sort((char[]) a, SEQUENTIAL, 0, ((char[]) a).length);
|
||||
} else if (a instanceof short[]) {
|
||||
DualPivotQuicksort.sort((short[]) a, SEQUENTIAL, 0, ((short[]) a).length);
|
||||
} else if (a instanceof float[]) {
|
||||
DualPivotQuicksort.sort((float[]) a, SEQUENTIAL, 0, ((float[]) a).length);
|
||||
} else if (a instanceof double[]) {
|
||||
DualPivotQuicksort.sort((double[]) a, SEQUENTIAL, 0, ((double[]) a).length);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object a, int low, int high) {
|
||||
if (a instanceof int[]) {
|
||||
DualPivotQuicksort.sort((int[]) a, SEQUENTIAL, low, high);
|
||||
} else if (a instanceof long[]) {
|
||||
DualPivotQuicksort.sort((long[]) a, SEQUENTIAL, low, high);
|
||||
} else if (a instanceof byte[]) {
|
||||
DualPivotQuicksort.sort((byte[]) a, low, high);
|
||||
} else if (a instanceof char[]) {
|
||||
DualPivotQuicksort.sort((char[]) a, SEQUENTIAL, low, high);
|
||||
} else if (a instanceof short[]) {
|
||||
DualPivotQuicksort.sort((short[]) a, SEQUENTIAL, low, high);
|
||||
} else if (a instanceof float[]) {
|
||||
DualPivotQuicksort.sort((float[]) a, SEQUENTIAL, low, high);
|
||||
} else if (a instanceof double[]) {
|
||||
DualPivotQuicksort.sort((double[]) a, SEQUENTIAL, low, high);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a) {
|
||||
fail(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a, Comparator comparator) {
|
||||
fail(a);
|
||||
}
|
||||
},
|
||||
|
||||
PARALLEL_SORT("Parallel sort") {
|
||||
|
||||
@Override
|
||||
public void sort(Object a) {
|
||||
if (a instanceof int[]) {
|
||||
DualPivotQuicksort.sort((int[]) a, PARALLEL, 0, ((int[]) a).length);
|
||||
} else if (a instanceof long[]) {
|
||||
DualPivotQuicksort.sort((long[]) a, PARALLEL, 0, ((long[]) a).length);
|
||||
} else if (a instanceof byte[]) {
|
||||
DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
|
||||
} else if (a instanceof char[]) {
|
||||
DualPivotQuicksort.sort((char[]) a, PARALLEL, 0, ((char[]) a).length);
|
||||
} else if (a instanceof short[]) {
|
||||
DualPivotQuicksort.sort((short[]) a, PARALLEL, 0, ((short[]) a).length);
|
||||
} else if (a instanceof float[]) {
|
||||
DualPivotQuicksort.sort((float[]) a, PARALLEL, 0, ((float[]) a).length);
|
||||
} else if (a instanceof double[]) {
|
||||
DualPivotQuicksort.sort((double[]) a, PARALLEL, 0, ((double[]) a).length);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object a, int low, int high) {
|
||||
if (a instanceof int[]) {
|
||||
DualPivotQuicksort.sort((int[]) a, PARALLEL, low, high);
|
||||
} else if (a instanceof long[]) {
|
||||
DualPivotQuicksort.sort((long[]) a, PARALLEL, low, high);
|
||||
} else if (a instanceof byte[]) {
|
||||
DualPivotQuicksort.sort((byte[]) a, low, high);
|
||||
} else if (a instanceof char[]) {
|
||||
DualPivotQuicksort.sort((char[]) a, PARALLEL, low, high);
|
||||
} else if (a instanceof short[]) {
|
||||
DualPivotQuicksort.sort((short[]) a, PARALLEL, low, high);
|
||||
} else if (a instanceof float[]) {
|
||||
DualPivotQuicksort.sort((float[]) a, PARALLEL, low, high);
|
||||
} else if (a instanceof double[]) {
|
||||
DualPivotQuicksort.sort((double[]) a, PARALLEL, low, high);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a) {
|
||||
fail(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a, Comparator comparator) {
|
||||
fail(a);
|
||||
}
|
||||
},
|
||||
|
||||
HEAP_SORT("Heap sort") {
|
||||
|
||||
@Override
|
||||
public void sort(Object a) {
|
||||
if (a instanceof int[]) {
|
||||
DualPivotQuicksort.sort(null, (int[]) a, BIG_DEPTH, 0, ((int[]) a).length);
|
||||
} else if (a instanceof long[]) {
|
||||
DualPivotQuicksort.sort(null, (long[]) a, BIG_DEPTH, 0, ((long[]) a).length);
|
||||
} else if (a instanceof byte[]) {
|
||||
DualPivotQuicksort.sort((byte[]) a, 0, ((byte[]) a).length);
|
||||
} else if (a instanceof char[]) {
|
||||
DualPivotQuicksort.sort((char[]) a, BIG_DEPTH, 0, ((char[]) a).length);
|
||||
} else if (a instanceof short[]) {
|
||||
DualPivotQuicksort.sort((short[]) a, BIG_DEPTH, 0, ((short[]) a).length);
|
||||
} else if (a instanceof float[]) {
|
||||
DualPivotQuicksort.sort(null, (float[]) a, BIG_DEPTH, 0, ((float[]) a).length);
|
||||
} else if (a instanceof double[]) {
|
||||
DualPivotQuicksort.sort(null, (double[]) a, BIG_DEPTH, 0, ((double[]) a).length);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object a, int low, int high) {
|
||||
if (a instanceof int[]) {
|
||||
DualPivotQuicksort.sort(null, (int[]) a, BIG_DEPTH, low, high);
|
||||
} else if (a instanceof long[]) {
|
||||
DualPivotQuicksort.sort(null, (long[]) a, BIG_DEPTH, low, high);
|
||||
} else if (a instanceof byte[]) {
|
||||
DualPivotQuicksort.sort((byte[]) a, low, high);
|
||||
} else if (a instanceof char[]) {
|
||||
DualPivotQuicksort.sort((char[]) a, BIG_DEPTH, low, high);
|
||||
} else if (a instanceof short[]) {
|
||||
DualPivotQuicksort.sort((short[]) a, BIG_DEPTH, low, high);
|
||||
} else if (a instanceof float[]) {
|
||||
DualPivotQuicksort.sort(null, (float[]) a, BIG_DEPTH, low, high);
|
||||
} else if (a instanceof double[]) {
|
||||
DualPivotQuicksort.sort(null, (double[]) a, BIG_DEPTH, low, high);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a) {
|
||||
fail(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a, Comparator comparator) {
|
||||
fail(a);
|
||||
}
|
||||
},
|
||||
|
||||
ARRAYS_SORT("Arrays.sort") {
|
||||
|
||||
@Override
|
||||
public void sort(Object a) {
|
||||
if (a instanceof int[]) {
|
||||
Arrays.sort((int[]) a);
|
||||
} else if (a instanceof long[]) {
|
||||
Arrays.sort((long[]) a);
|
||||
} else if (a instanceof byte[]) {
|
||||
Arrays.sort((byte[]) a);
|
||||
} else if (a instanceof char[]) {
|
||||
Arrays.sort((char[]) a);
|
||||
} else if (a instanceof short[]) {
|
||||
Arrays.sort((short[]) a);
|
||||
} else if (a instanceof float[]) {
|
||||
Arrays.sort((float[]) a);
|
||||
} else if (a instanceof double[]) {
|
||||
Arrays.sort((double[]) a);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object a, int low, int high) {
|
||||
if (a instanceof int[]) {
|
||||
Arrays.sort((int[]) a, low, high);
|
||||
} else if (a instanceof long[]) {
|
||||
Arrays.sort((long[]) a, low, high);
|
||||
} else if (a instanceof byte[]) {
|
||||
Arrays.sort((byte[]) a, low, high);
|
||||
} else if (a instanceof char[]) {
|
||||
Arrays.sort((char[]) a, low, high);
|
||||
} else if (a instanceof short[]) {
|
||||
Arrays.sort((short[]) a, low, high);
|
||||
} else if (a instanceof float[]) {
|
||||
Arrays.sort((float[]) a, low, high);
|
||||
} else if (a instanceof double[]) {
|
||||
Arrays.sort((double[]) a, low, high);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object[] a) {
|
||||
Arrays.sort(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sort(Object[] a, Comparator comparator) {
|
||||
Arrays.sort(a, comparator);
|
||||
}
|
||||
},
|
||||
|
||||
ARRAYS_PARALLEL_SORT("Arrays.parallelSort") {
|
||||
|
||||
@Override
|
||||
public void sort(Object a) {
|
||||
if (a instanceof int[]) {
|
||||
Arrays.parallelSort((int[]) a);
|
||||
} else if (a instanceof long[]) {
|
||||
Arrays.parallelSort((long[]) a);
|
||||
} else if (a instanceof byte[]) {
|
||||
Arrays.parallelSort((byte[]) a);
|
||||
} else if (a instanceof char[]) {
|
||||
Arrays.parallelSort((char[]) a);
|
||||
} else if (a instanceof short[]) {
|
||||
Arrays.parallelSort((short[]) a);
|
||||
} else if (a instanceof float[]) {
|
||||
Arrays.parallelSort((float[]) a);
|
||||
} else if (a instanceof double[]) {
|
||||
Arrays.parallelSort((double[]) a);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Object a, int low, int high) {
|
||||
if (a instanceof int[]) {
|
||||
Arrays.parallelSort((int[]) a, low, high);
|
||||
} else if (a instanceof long[]) {
|
||||
Arrays.parallelSort((long[]) a, low, high);
|
||||
} else if (a instanceof byte[]) {
|
||||
Arrays.parallelSort((byte[]) a, low, high);
|
||||
} else if (a instanceof char[]) {
|
||||
Arrays.parallelSort((char[]) a, low, high);
|
||||
} else if (a instanceof short[]) {
|
||||
Arrays.parallelSort((short[]) a, low, high);
|
||||
} else if (a instanceof float[]) {
|
||||
Arrays.parallelSort((float[]) a, low, high);
|
||||
} else if (a instanceof double[]) {
|
||||
Arrays.parallelSort((double[]) a, low, high);
|
||||
} else {
|
||||
fail(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sort(Object[] a) {
|
||||
Arrays.parallelSort((Comparable[]) a);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sort(Object[] a, Comparator comparator) {
|
||||
Arrays.parallelSort(a, comparator);
|
||||
}
|
||||
};
|
||||
|
||||
abstract public void sort(Object a);
|
||||
|
||||
abstract public void sort(Object a, int low, int high);
|
||||
|
||||
abstract public void sort(Object[] a);
|
||||
|
||||
abstract public void sort(Object[] a, Comparator comparator);
|
||||
|
||||
private SortingHelper(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private static void fail(Object a) {
|
||||
throw new RuntimeException("Unexpected type of array: " + a.getClass().getName());
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Parallelism level for sequential and parallel sorting.
|
||||
*/
|
||||
private static final int SEQUENTIAL = 0;
|
||||
private static final int PARALLEL = 87;
|
||||
|
||||
/**
|
||||
* Heap sort will be invoked, if recursion depth is too big.
|
||||
* Value is taken from DualPivotQuicksort.MAX_RECURSION_DEPTH.
|
||||
*/
|
||||
private static final int BIG_DEPTH = 64 * (3 << 1);
|
||||
}
|
Loading…
Reference in New Issue
Block a user