forked from Speiger/Primitive-Collections
Added Parallel Sorting Methods.
This commit is contained in:
parent
66430d5a8a
commit
0c53fbab6b
|
@ -1,39 +1,50 @@
|
||||||
package speiger.src.collections.utils;
|
package speiger.src.collections.utils;
|
||||||
|
|
||||||
|
import java.util.concurrent.ForkJoinPool;
|
||||||
|
import java.util.concurrent.ForkJoinTask;
|
||||||
|
|
||||||
public class SanityChecks
|
public class SanityChecks
|
||||||
{
|
{
|
||||||
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
|
||||||
|
private static ForkJoinPool WORK_POOL = ForkJoinPool.commonPool();
|
||||||
|
|
||||||
public static byte castToByte(int value)
|
public static byte castToByte(int value) {
|
||||||
{
|
|
||||||
if(value > Byte.MAX_VALUE || value < Byte.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Byte[-128,127] range");
|
if(value > Byte.MAX_VALUE || value < Byte.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Byte[-128,127] range");
|
||||||
return (byte)value;
|
return (byte)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static short castToShort(int value)
|
public static short castToShort(int value) {
|
||||||
{
|
|
||||||
if(value > Short.MAX_VALUE || value < Short.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Short[-32768,32767] range");
|
if(value > Short.MAX_VALUE || value < Short.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Short[-32768,32767] range");
|
||||||
return (short)value;
|
return (short)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char castToChar(int value)
|
public static char castToChar(int value) {
|
||||||
{
|
|
||||||
if(value > Character.MAX_VALUE || value < Character.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Character[0,65535] range");
|
if(value > Character.MAX_VALUE || value < Character.MIN_VALUE) throw new IllegalStateException("Value ["+value+"] out of Character[0,65535] range");
|
||||||
return (char)value;
|
return (char)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float castToFloat(double value)
|
public static float castToFloat(double value) {
|
||||||
{
|
|
||||||
if(Double.isNaN(value)) return Float.NaN;
|
if(Double.isNaN(value)) return Float.NaN;
|
||||||
if(Double.isInfinite(value)) return value > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
|
if(Double.isInfinite(value)) return value > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
|
||||||
if(value < -Float.MAX_VALUE || value > Float.MAX_VALUE) throw new IllegalStateException("Value ["+value+"] out of Float range");
|
if(value < -Float.MAX_VALUE || value > Float.MAX_VALUE) throw new IllegalStateException("Value ["+value+"] out of Float range");
|
||||||
return (float)value;
|
return (float)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkArrayCapacity(int arraySize, int offset, int accessSize)
|
public static void checkArrayCapacity(int arraySize, int offset, int accessSize) {
|
||||||
{
|
|
||||||
if(offset < 0) throw new IllegalStateException("Offset is negative ("+offset+")");
|
if(offset < 0) throw new IllegalStateException("Offset is negative ("+offset+")");
|
||||||
else if(accessSize < 0) throw new IllegalStateException("Size is negative ("+accessSize+")");
|
else if(accessSize < 0) throw new IllegalStateException("Size is negative ("+accessSize+")");
|
||||||
else if(arraySize < offset + accessSize) throw new IndexOutOfBoundsException("Index (" + offset + accessSize + ") is not in size (" + arraySize + ")");
|
else if(arraySize < offset + accessSize) throw new IndexOutOfBoundsException("Index (" + offset + accessSize + ") is not in size (" + arraySize + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean canParallelTask() {
|
||||||
|
return WORK_POOL.getParallelism() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void invokeTask(ForkJoinTask<T> task) {
|
||||||
|
WORK_POOL.invoke(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setWorkPool(ForkJoinPool pool) {
|
||||||
|
WORK_POOL = pool == null ? ForkJoinPool.commonPool() : pool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,20 @@ package speiger.src.collections.PACKAGE.utils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.RecursiveAction;
|
import java.util.concurrent.RecursiveAction;
|
||||||
|
|
||||||
#if !TYPE_OBJECT
|
#if !TYPE_OBJECT
|
||||||
|
|
||||||
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
|
||||||
import speiger.src.collections.utils.SanityChecks;
|
|
||||||
#else
|
#else
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
import speiger.src.collections.utils.SanityChecks;
|
||||||
|
|
||||||
public class ARRAYS
|
public class ARRAYS
|
||||||
{
|
{
|
||||||
|
public static final int BASE_THRESHOLD = 16;
|
||||||
|
public static final int PARALLEL_THRESHOLD = 8192;
|
||||||
|
|
||||||
#if !TYPE_OBJECT
|
#if !TYPE_OBJECT
|
||||||
public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0];
|
public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0];
|
||||||
|
|
||||||
|
@ -151,7 +155,7 @@ public class ARRAYS
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GENERIC_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
public static GENERIC_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
if(to - from < 16) {
|
if(to - from < BASE_THRESHOLD) {
|
||||||
insertionSort(array, from, to, comp);
|
insertionSort(array, from, to, comp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +183,7 @@ public class ARRAYS
|
||||||
}
|
}
|
||||||
|
|
||||||
public static COMPAREABLE_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
|
public static COMPAREABLE_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
|
||||||
if(to - from < 16) {
|
if(to - from < BASE_THRESHOLD) {
|
||||||
insertionSort(array, from, to);
|
insertionSort(array, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -198,6 +202,38 @@ public class ARRAYS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
parallelMergeSort(array, null, 0, array.length, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
parallelMergeSort(array, null, 0, length, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||||
|
SanityChecks.invokeTask(new MergeSortActionCompBRACES(array, supp, from, to, comp));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mergeSort(array, supp, from, to, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelMergeSort(KEY_TYPE[] array) {
|
||||||
|
parallelMergeSort(array, null, 0, array.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelMergeSort(KEY_TYPE[] array, int length) {
|
||||||
|
parallelMergeSort(array, null, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
|
||||||
|
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||||
|
SanityChecks.invokeTask(new MergeSortActionBRACES(array, supp, from, to));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mergeSort(array, supp, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
memFreeMergeSort(array, 0, array.length, comp);
|
memFreeMergeSort(array, 0, array.length, comp);
|
||||||
}
|
}
|
||||||
|
@ -207,7 +243,7 @@ public class ARRAYS
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
public static GENERIC_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
if(to - from < 16) {
|
if(to - from < BASE_THRESHOLD) {
|
||||||
insertionSort(array, from, to, comp);
|
insertionSort(array, from, to, comp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +278,7 @@ public class ARRAYS
|
||||||
}
|
}
|
||||||
|
|
||||||
public static COMPAREABLE_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to) {
|
public static COMPAREABLE_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to) {
|
||||||
if(to - from < 16) {
|
if(to - from < BASE_THRESHOLD) {
|
||||||
insertionSort(array, from, to);
|
insertionSort(array, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -268,6 +304,38 @@ public class ARRAYS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
parallelMemFreeMergeSort(array, 0, array.length, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
parallelMemFreeMergeSort(array, 0, length, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||||
|
SanityChecks.invokeTask(new MemFreeMergeSortActionCompBRACES(array, from, to, comp));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memFreeMergeSort(array, from, to, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array) {
|
||||||
|
parallelMemFreeMergeSort(array, 0, array.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int length) {
|
||||||
|
parallelMemFreeMergeSort(array, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int from, int to) {
|
||||||
|
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||||
|
SanityChecks.invokeTask(new MemFreeMergeSortActionBRACES(array, from, to));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memFreeMergeSort(array, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
quickSort(array, 0, array.length, comp);
|
quickSort(array, 0, array.length, comp);
|
||||||
}
|
}
|
||||||
|
@ -279,7 +347,7 @@ public class ARRAYS
|
||||||
public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
public static GENERIC_BRACES void quickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
int length = to - from;
|
int length = to - from;
|
||||||
if(length <= 0) return;
|
if(length <= 0) return;
|
||||||
if(length < 16) {
|
if(length < BASE_THRESHOLD) {
|
||||||
selectionSort(array, from, to, comp);
|
selectionSort(array, from, to, comp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +379,7 @@ public class ARRAYS
|
||||||
public static COMPAREABLE_BRACES void quickSort(KEY_TYPE[] array, int from, int to) {
|
public static COMPAREABLE_BRACES void quickSort(KEY_TYPE[] array, int from, int to) {
|
||||||
int length = to - from;
|
int length = to - from;
|
||||||
if(length <= 0) return;
|
if(length <= 0) return;
|
||||||
if(length < 16) {
|
if(length < BASE_THRESHOLD) {
|
||||||
selectionSort(array, from, to);
|
selectionSort(array, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -332,6 +400,38 @@ public class ARRAYS
|
||||||
if((length = d - c) > 1) quickSort(array, to - length, to);
|
if((length = d - c) > 1) quickSort(array, to - length, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
parallelQuickSort(array, 0, array.length, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
parallelQuickSort(array, 0, length, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GENERIC_BRACES void parallelQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||||
|
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||||
|
SanityChecks.invokeTask(new QuickSortActionCompBRACES(array, from, to, comp));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
quickSort(array, from, to, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelQuickSort(KEY_TYPE[] array) {
|
||||||
|
parallelQuickSort(array, 0, array.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelQuickSort(KEY_TYPE[] array, int length) {
|
||||||
|
parallelQuickSort(array, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static COMPAREABLE_BRACES void parallelQuickSort(KEY_TYPE[] array, int from, int to) {
|
||||||
|
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||||
|
SanityChecks.invokeTask(new QuickSortActionBRACES(array, from, to));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
quickSort(array, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
public static GENERIC_BRACES void swap(KEY_TYPE[] a, int from, int to) {
|
public static GENERIC_BRACES void swap(KEY_TYPE[] a, int from, int to) {
|
||||||
KEY_TYPE t = a[from];
|
KEY_TYPE t = a[from];
|
||||||
a[from] = a[to];
|
a[from] = a[to];
|
||||||
|
@ -377,7 +477,7 @@ public class ARRAYS
|
||||||
{
|
{
|
||||||
int length = to - from;
|
int length = to - from;
|
||||||
if(length <= 0) return;
|
if(length <= 0) return;
|
||||||
if(length < 16) {
|
if(length < BASE_THRESHOLD) {
|
||||||
selectionSort(array, from, to);
|
selectionSort(array, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +520,7 @@ public class ARRAYS
|
||||||
{
|
{
|
||||||
int length = to - from;
|
int length = to - from;
|
||||||
if(length <= 0) return;
|
if(length <= 0) return;
|
||||||
if(length < 16) {
|
if(length < BASE_THRESHOLD) {
|
||||||
selectionSort(array, from, to, comp);
|
selectionSort(array, from, to, comp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -442,4 +542,167 @@ public class ARRAYS
|
||||||
else if(d - c > 1) new QuickSortActionCompBRACES(array, to - (d - c), to, comp).invoke();
|
else if(d - c > 1) new QuickSortActionCompBRACES(array, to - (d - c), to, comp).invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class MergeSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction {
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
KEY_TYPE[] array;
|
||||||
|
KEY_TYPE[] supp;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
|
||||||
|
MergeSortAction(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
this.supp = supp;
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compute()
|
||||||
|
{
|
||||||
|
if(to - from < BASE_THRESHOLD) {
|
||||||
|
insertionSort(array, from, to);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||||
|
int mid = (from + to) >>> 1;
|
||||||
|
invokeAll(new MergeSortActionBRACES(supp, array, from, mid), new MergeSortActionBRACES(supp, array, mid, to));
|
||||||
|
if(COMPARE_TO(supp[mid - 1], supp[mid]) <= 0)
|
||||||
|
{
|
||||||
|
System.arraycopy(supp, from, array, from, to - from);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(int p = from, q = mid;from < to;from++) {
|
||||||
|
if(q >= to || p < mid && COMPARE_TO(supp[p], supp[q]) < 0) array[from] = supp[p++];
|
||||||
|
else array[from] = supp[q++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MergeSortActionComp KEY_GENERIC_TYPE extends RecursiveAction {
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
KEY_TYPE[] array;
|
||||||
|
KEY_TYPE[] supp;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||||
|
|
||||||
|
MergeSortActionComp(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
this.supp = supp;
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.comp = comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compute()
|
||||||
|
{
|
||||||
|
if(to - from < BASE_THRESHOLD) {
|
||||||
|
insertionSort(array, from, to, comp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||||
|
int mid = (from + to) >>> 1;
|
||||||
|
invokeAll(new MergeSortActionCompBRACES(supp, array, from, mid, comp), new MergeSortActionCompBRACES(supp, array, mid, to, comp));
|
||||||
|
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||||
|
{
|
||||||
|
System.arraycopy(supp, from, array, from, to - from);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(int p = from, q = mid;from < to;from++) {
|
||||||
|
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) array[from] = supp[p++];
|
||||||
|
else array[from] = supp[q++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MemFreeMergeSortAction KEY_COMPAREABLE_TYPE extends RecursiveAction {
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
KEY_TYPE[] array;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
|
||||||
|
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compute()
|
||||||
|
{
|
||||||
|
if(to - from < BASE_THRESHOLD) {
|
||||||
|
insertionSort(array, from, to);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int mid = (from + to) >>> 1;
|
||||||
|
invokeAll(new MemFreeMergeSortActionBRACES(array, from, mid), new MemFreeMergeSortActionBRACES(array, mid, to));
|
||||||
|
if(COMPARE_TO(array[mid - 1], array[mid]) <= 0)
|
||||||
|
return;
|
||||||
|
for(int i = from, j = mid, comp;i < j && j < to;) {
|
||||||
|
if((comp = COMPARE_TO(array[i], array[j])) < 0)
|
||||||
|
i++;
|
||||||
|
else if(comp == 0) swap(array, ++i, j);
|
||||||
|
else {
|
||||||
|
swap(array, i++, j);
|
||||||
|
int k = j;
|
||||||
|
for(;k < to - 1 && COMPARE_TO(array[j], array[k + 1]) > 0;k++);
|
||||||
|
if(j == k)
|
||||||
|
continue;
|
||||||
|
KEY_TYPE value = array[j];
|
||||||
|
System.arraycopy(array, j + 1, array, j, k - j);
|
||||||
|
array[k] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class MemFreeMergeSortActionComp KEY_GENERIC_TYPE extends RecursiveAction {
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
KEY_TYPE[] array;
|
||||||
|
int from;
|
||||||
|
int to;
|
||||||
|
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||||
|
|
||||||
|
MemFreeMergeSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||||||
|
{
|
||||||
|
this.array = array;
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.comp = comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compute()
|
||||||
|
{
|
||||||
|
if(to - from < BASE_THRESHOLD) {
|
||||||
|
insertionSort(array, from, to, comp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int mid = (from + to) >>> 1;
|
||||||
|
invokeAll(new MemFreeMergeSortActionCompBRACES(array, from, mid, comp), new MemFreeMergeSortActionCompBRACES(array, mid, to, comp));
|
||||||
|
|
||||||
|
if(comp.compare(array[mid - 1], array[mid]) <= 0)
|
||||||
|
return;
|
||||||
|
for(int i = from, j = mid, compare;i < j && j < to;) {
|
||||||
|
if((compare = comp.compare(array[i], array[j])) < 0)
|
||||||
|
i++;
|
||||||
|
else if(compare == 0) swap(array, ++i, j);
|
||||||
|
else {
|
||||||
|
swap(array, i++, j);
|
||||||
|
int k = j;
|
||||||
|
for(;k < to - 1 && comp.compare(array[j], array[k + 1]) > 0;k++);
|
||||||
|
if(j == k)
|
||||||
|
continue;
|
||||||
|
KEY_TYPE value = array[j];
|
||||||
|
System.arraycopy(array, j + 1, array, j, k - j);
|
||||||
|
array[k] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue