package speiger.src.collections.PACKAGE.utils; import java.util.Arrays; import java.util.Random; import java.util.concurrent.RecursiveAction; #if !TYPE_OBJECT import speiger.src.collections.PACKAGE.functions.COMPARATOR; #else import java.util.Comparator; #endif import speiger.src.collections.PACKAGE.collections.ITERATOR; import speiger.src.collections.PACKAGE.lists.ARRAY_LIST; import speiger.src.collections.PACKAGE.utils.ITERATORS; import speiger.src.collections.utils.SanityChecks; /** * A Helper class for Arrays */ public class ARRAYS { /** Default Limit for Insertion/Selection Sort */ public static final int BASE_THRESHOLD = 16; /** Default Threshold for Multithreaded Sorting Algorythm options*/ public static final int PARALLEL_THRESHOLD = 8192; #if !TYPE_OBJECT /** Empty Array Reference used for Uninitialized Collections */ public static final KEY_TYPE[] EMPTY_ARRAY = new KEY_TYPE[0]; /** * A Helper function to convert a Primitive Array to a CLASS_TYPE Array. * @param a the array that should be converted * @return a CLASS_TYPE Array of the input array. */ public static CLASS_TYPE[] wrap(KEY_TYPE[] a) { return wrap(a, 0, a.length); } /** * A Helper function to convert a Primitive Array to a CLASS_TYPE Array. * @param a the array that should be converted * @param length the maximum length that should be coverted * @return a CLASS_TYPE Array of the input array. */ public static CLASS_TYPE[] wrap(KEY_TYPE[] a, int length) { return wrap(a, 0, length); } /** * A Helper function to convert a Primitive Array to a CLASS_TYPE Array. * @param a the array that should be converted * @param offset the starting offset of the inputarray * @param length the maximum length that should be coverted * @return a CLASS_TYPE Array of the input array. */ public static CLASS_TYPE[] wrap(KEY_TYPE[] a, int offset, int length) { SanityChecks.checkArrayCapacity(a.length, offset, length); CLASS_TYPE[] result = new CLASS_TYPE[length]; for(int i = offset;i clz, int length) { if(clz == Object.class) return (KEY_TYPE[])new Object[length]; return (KEY_TYPE[]) java.lang.reflect.Array.newInstance(clz, length); } #endif /** * A Helper function that pours all elements of a iterator into a Array * @param iter the elements that should be gathered. * @ArrayType(T) * @return array with all elements of the iterator */ public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter) { return pour(iter, Integer.MAX_VALUE); } /** * A Helper function that pours all elements of a iterator into a Array * @param iter the elements that should be gathered. * @param max how many elements should be added * @ArrayType(T) * @return array with all requested elements of the iterator */ public static GENERIC_KEY_BRACES KEY_TYPE[] pour(ITERATOR KEY_GENERIC_TYPE iter, int max) { ARRAY_LIST KEY_GENERIC_TYPE list = new ARRAY_LISTBRACES(); ITERATORS.pour(iter, list, max); return list.TO_ARRAY(NEW_KEY_ARRAY(list.size())); } /** * Method to validate if the current value is the lowest value in the heap * @param data the current heap. * @param size the size of the heap * @param index the index that should be validated * @param comp the comparator to sort the heap. Can be null * @ArrayType(T) * @return the index the element was shifted to */ public static GENERIC_KEY_BRACES int shiftDown(KEY_TYPE[] data, int size, int index, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { int half = size >>> 1; KEY_TYPE value = data[index]; if(comp != null) { while(index < half) { int child = (index << 1) + 1; KEY_TYPE childValue = data[child]; int right = child+1; if(right < size && comp.compare(data[right], childValue) < 0) childValue = data[child = right]; if(comp.compare(value, childValue) <= 0) break; data[index] = childValue; index = child; } } else { while(index < half) { int child = (index << 1) + 1; KEY_TYPE childValue = data[child]; int right = child+1; if(right < size && COMPAREABLE_TO_KEY(data[right], childValue) < 0) childValue = data[child = right]; if(COMPAREABLE_TO_KEY(value, childValue) <= 0) break; data[index] = childValue; index = child; } } data[index] = value; return index; } /** * Method to sort a specific value into the heap. * @param data the heap itself. * @param index that should be heapified. * @param comp the comparator to sort the heap. Can be null * @ArrayType(T) * @return the index the element was shifted to */ public static GENERIC_KEY_BRACES int shiftUp(KEY_TYPE[] data, int index, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { KEY_TYPE value = data[index]; if(comp != null) { while(index > 0) { int parent = (index - 1) >>> 1; KEY_TYPE parentValue = data[parent]; if(comp.compare(value, parentValue) >= 0) break; data[index] = parentValue; index = parent; } } else { while(index > 0) { int parent = (index - 1) >>> 1; KEY_TYPE parentValue = data[parent]; if(COMPAREABLE_TO_KEY(value, parentValue) >= 0) break; data[index] = parentValue; index = parent; } } data[index] = value; return index; } /** * Helper function to create a Heap out of an array. * @param data the array to heapify * @param size the current size of elements within the array. * @param comp the Comparator to sort the array. Can be null * @ArrayType(T) * @return the input array */ public static GENERIC_KEY_BRACES KEY_TYPE[] heapify(KEY_TYPE[] data, int size, COMPARATOR KEY_SUPER_GENERIC_TYPE comp) { for(int i = (size >>> 1) - 1;i>=0;shiftDown(data, size, i--, comp)); return data; } /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled * @ArrayType(T) * @note This uses the SanityChecks#getRandom * @return the provided sorted array */ public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array) { return shuffle(array, SanityChecks.getRandom()); } /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled * @param length the length of the array * @ArrayType(T) * @note This uses the SanityChecks#getRandom * @return the provided sorted array */ public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length) { return shuffle(array, 0, length, SanityChecks.getRandom()); } /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled * @param offset the start array * @param length the length of the array * @ArrayType(T) * @note This uses the SanityChecks#getRandom * @return the provided sorted array */ public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length) { return shuffle(array, offset, length, SanityChecks.getRandom()); } /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled * @param random the Random Number Generator that should be used for the shuffling * @ArrayType(T) * @return the provided sorted array */ public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, Random random) { for(int i = array.length-1; i>=0;i--) { int p = random.nextInt(i + 1); KEY_TYPE t = array[i]; array[i] = array[p]; array[p] = t; } return array; } /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled * @param length the length of the array * @param random the Random Number Generator that should be used for the shuffling * @ArrayType(T) * @return the provided sorted array */ public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int length, Random random) { return shuffle(array, 0, length, random); } /** * Simple Shuffle method for Arrays. * @param array the elements that should be shuffled * @param offset the start array * @param length the length of the array * @param random the Random Number Generator that should be used for the shuffling * @ArrayType(T) * @return the provided sorted array */ public static GENERIC_KEY_BRACES KEY_TYPE[] shuffle(KEY_TYPE[] array, int offset, int length, Random random) { for(int i = length-1; i>=0;i--) { int p = offset + random.nextInt(i + 1); KEY_TYPE t = array[offset+i]; array[offset+i] = array[p]; array[p] = t; } return array; } /** * Simple Array Reversal method * @param array the Array that should flip * @ArrayType(T) * @return the provided array */ public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array) { return reverse(array, 0, array.length); } /** * Simple Array Reversal method * @param array the Array that should flip * @param length the length of the array * @ArrayType(T) * @return the provided array */ public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array, int length) { return reverse(array, 0, length); } /** * Simple Array Reversal method * @param array the Array that should flip * @param length the length of the array * @param offset the start of the array * @ArrayType(T) * @return the provided array */ public static GENERIC_KEY_BRACES KEY_TYPE[] reverse(KEY_TYPE[] array, int offset, int length) { for (int i = offset, mid = offset + length >> 1, j = offset + length - 1; i < mid; i++, j--) { KEY_TYPE temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Stable sort referres to Mergesort or Insertionsort * @param array the array that needs to be sorted * @ArrayType(T) * @param comp the Comparator that decides the sorting order */ public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { stableSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Stable sort referres to Mergesort or Insertionsort * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { stableSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Stable sort referres to Mergesort or Insertionsort * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { mergeSort(array, null, from, to, comp); } /** * Sorts an array according to the natural ascending order, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Stable sort referres to Mergesort or Insertionsort * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array) { stableSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Stable sort referres to Mergesort or Insertionsort * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, int length) { stableSort(array, 0, length); } /** * Sorts an array according to the natural ascending order, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Stable sort referres to Mergesort or Insertionsort * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void stableSort(KEY_TYPE[] array, int from, int to) { mergeSort(array, null, from, to); } /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Unstable sort referres to QuickSort or SelectionSort * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { unstableSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Unstable sort referres to QuickSort or SelectionSort * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { unstableSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Unstable sort referres to QuickSort or SelectionSort * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { quickSort(array, from, to, comp); } /** * Sorts an array according to the natural ascending order, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Unstable sort referres to QuickSort or SelectionSort * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array) { unstableSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Unstable sort referres to QuickSort or SelectionSort * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, int length) { unstableSort(array, 0, length); } /** * Sorts an array according to the natural ascending order, * potentially dynamically choosing an appropriate algorithm given the type and size of the array. * Unstable sort referres to QuickSort or SelectionSort * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void unstableSort(KEY_TYPE[] array, int from, int to) { quickSort(array, from, to); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort, * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { insertionSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort, * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { insertionSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort, * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { for (int i = from+1;i= from && comp.compare(current, array[j]) < 0) { array[j+1] = array[j--]; } array[j+1] = current; } } /** * Sorts an array according to the natural ascending order using InsertionSort, * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array) { insertionSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order using InsertionSort, * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int length) { insertionSort(array, 0, length); } /** * Sorts an array according to the natural ascending order using InsertionSort, * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void insertionSort(KEY_TYPE[] array, int from, int to) { for (int i = from+1;i= from && COMPAREABLE_TO_KEY(current, array[j]) < 0) { array[j+1] = array[j--]; } array[j+1] = current; } } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort, * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { selectionSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort, * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { selectionSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort, * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { for (int i = from; i < to; i++) { KEY_TYPE min = array[i]; int minId = i; for(int j = i+1; j < to; j++) { if(comp.compare(array[j], min) < 0) { min = array[j]; minId = j; } } KEY_TYPE temp = array[i]; array[i] = min; array[minId] = temp; } } /** * Sorts an array according to the natural ascending order using Selection Sort, * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array) { selectionSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order using Selection Sort, * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int length) { selectionSort(array, 0, length); } /** * Sorts an array according to the natural ascending order using Selection Sort, * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void selectionSort(KEY_TYPE[] array, int from, int to) { for (int i = from; i < to; i++) { KEY_TYPE min = array[i]; int minId = i; for(int j = i+1; j < to; j++) { if(COMPAREABLE_TO_KEY(array[j], min) < 0) { min = array[j]; minId = j; } } KEY_TYPE temp = array[i]; array[i] = min; array[minId] = temp; } } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { mergeSort(array, null, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { mergeSort(array, null, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param supp the auxillary array that is used to simplify the sorting * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { if(to - from < BASE_THRESHOLD) { insertionSort(array, from, to, comp); return; } if(supp == null) supp = Arrays.copyOf(array, to); int mid = (from + to) >>> 1; mergeSort(supp, array, from, mid, comp); mergeSort(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++]; } } /** * Sorts an array according to the natural ascending order using Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array) { mergeSort(array, null, 0, array.length); } /** * Sorts an array according to the natural ascending order using Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, int length) { mergeSort(array, null, 0, length); } /** * Sorts an array according to the natural ascending order using Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param supp the auxillary array that is used to simplify the sorting * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void mergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) { if(to - from < BASE_THRESHOLD) { insertionSort(array, from, to); return; } if(supp == null) supp = Arrays.copyOf(array, to); int mid = (from + to) >>> 1; mergeSort(supp, array, from, mid); mergeSort(supp, array, mid, to); if(COMPAREABLE_TO_KEY(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 && COMPAREABLE_TO_KEY(supp[p], supp[q]) < 0) array[from] = supp[p++]; else array[from] = supp[q++]; } } /** * Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { parallelMergeSort(array, null, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { parallelMergeSort(array, null, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param supp the auxillary array that is used to simplify the sorting * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_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); } /** * Sorts an array according to the natural ascending order using Parallel Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array) { parallelMergeSort(array, null, 0, array.length); } /** * Sorts an array according to the natural ascending order using Parallel Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMergeSort(KEY_TYPE[] array, int length) { parallelMergeSort(array, null, 0, length); } /** * Sorts an array according to the natural ascending order using Parallel Merge Sort, * This implementation was copied from FastUtil with a couple custom optimizations * @param array the array that needs to be sorted * @param supp the auxillary array that is used to simplify the sorting * @param from where the array should be sorted from * @param to where the array should be sorted to * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_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); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast. * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { memFreeMergeSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast. * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { memFreeMergeSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. It is in Very Unsorted Instances 50% slower then Mergesort, otherwise it as fast. * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { if(to - from < BASE_THRESHOLD) { insertionSort(array, from, to, comp); return; } int mid = (from + to) >>> 1; memFreeMergeSort(array, from, mid, comp); memFreeMergeSort(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 { int k = j; for(;k < to - 1 && comp.compare(array[i], array[k + 1]) > 0;k++); if(j == k) { swap(array, i++, j); continue; } else if(j + 1 == k) { KEY_TYPE value = array[j]; System.arraycopy(array, i, array, i+1, j - i); array[i] = value; i++; j++; continue; } KEY_TYPE[] data = NEW_KEY_ARRAY(k - j); System.arraycopy(array, j, data, 0, data.length); System.arraycopy(array, i, array, i+data.length, j - i); System.arraycopy(data, 0, array, i, data.length); i+=data.length; j+=data.length; } } } /** * Sorts an array according to the natural ascending order using Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array) { memFreeMergeSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order using Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int length) { memFreeMergeSort(array, 0, length); } /** * Sorts an array according to the natural ascending order using Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void memFreeMergeSort(KEY_TYPE[] array, int from, int to) { if(to - from < BASE_THRESHOLD) { insertionSort(array, from, to); return; } int mid = (from + to) >>> 1; memFreeMergeSort(array, from, mid); memFreeMergeSort(array, mid, to); if(COMPAREABLE_TO_KEY(array[mid - 1], array[mid]) <= 0) return; for(int i = from, j = mid, comp;i < j && j < to;) { if((comp = COMPAREABLE_TO_KEY(array[i], array[j])) < 0) i++; else if(comp == 0) swap(array, ++i, j); else { int k = j; for(;k < to - 1 && COMPAREABLE_TO_KEY(array[i], array[k + 1]) > 0;k++); if(j == k) { swap(array, i++, j); continue; } else if(j + 1 == k) { KEY_TYPE value = array[j]; System.arraycopy(array, i, array, i+1, j - i); array[i] = value; i++; j++; continue; } KEY_TYPE[] data = NEW_KEY_ARRAY(k - j); System.arraycopy(array, j, data, 0, data.length); System.arraycopy(array, i, array, i+data.length, j - i); System.arraycopy(data, 0, array, i, data.length); i+=data.length; j+=data.length; } } } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { parallelMemFreeMergeSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { parallelMemFreeMergeSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_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); } /** * Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array) { parallelMemFreeMergeSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_BRACES void parallelMemFreeMergeSort(KEY_TYPE[] array, int length) { parallelMemFreeMergeSort(array, 0, length); } /** * Sorts an array according to the natural ascending order using Parallel Memory Free Merge Sort, * This implementation is inspired by FastUtil original merge sort, but without the need to allocate a copy of the original Array. * It is depending on the size and the unsorted level of the input array slower or almost as fast as normal merge sort. Depending on the test size i can be 0.5x slower (5000 elements) or 4x slower (50000 elements) under the assumtion that the array is in its worst case scenario. * It does stack allocate tiny amounts of data for shifting around elements. * @author Speiger * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed * @ArrayType(T) */ public static GENERIC_KEY_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); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { quickSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { quickSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) */ public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) { int length = to - from; if(length <= 0) return; if(length < BASE_THRESHOLD) { selectionSort(array, from, to, comp); return; } KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)]; int a = from, b = a, c = to - 1, d = c; for(int compare;;swap(array, b++, c--)) { for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) { if(compare == 0) swap(array, a++, b); } for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) { if(compare == 0) swap(array, c, d--); } if(b>c) break; } swap(array, from, b, Math.min(a - from, b - a)); swap(array, b, to, Math.min(d - c, to - d - 1)); if((length = b - a) > 1) quickSort(array, from, from + length, comp); if((length = d - c) > 1) quickSort(array, to - length, to, comp); } /** * Sorts an array according to the natural ascending order using Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array) { quickSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order using Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) */ public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, int length) { quickSort(array, 0, length); } /** * Sorts an array according to the natural ascending order using Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) */ public static GENERIC_KEY_BRACES void quickSort(KEY_TYPE[] array, int from, int to) { int length = to - from; if(length <= 0) return; if(length < BASE_THRESHOLD) { selectionSort(array, from, to); return; } KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)]; int a = from, b = a, c = to - 1, d = c; for(int comp = 0;;swap(array, b++, c--)) { for(;b<=c && (comp = COMPAREABLE_TO_KEY(array[b], pivot)) <= 0;b++) { if(comp == 0) swap(array, a++, b); } for(;c>=b && (comp = COMPAREABLE_TO_KEY(array[c], pivot)) >= 0;c--) { if(comp == 0) swap(array, c, d--); } if(b>c) break; } swap(array, from, b, Math.min(a - from, b - a)); swap(array, b, to, Math.min(d - c, to - d - 1)); if((length = b - a) > 1) quickSort(array, from, from + length); if((length = d - c) > 1) quickSort(array, to - length, to); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed */ public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp) { parallelQuickSort(array, 0, array.length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @param comp the Comparator that decides the sorting order * @ArrayType(T) * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed */ public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp) { parallelQuickSort(array, 0, length, comp); } /** * Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @param comp the Comparator that decides the sorting order * @ArrayType(T) * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed */ public static GENERIC_KEY_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); } /** * Sorts an array according to the natural ascending order using Parallel Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @ArrayType(T) * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed */ public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array) { parallelQuickSort(array, 0, array.length); } /** * Sorts an array according to the natural ascending order using Parallel Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param length the maxmium size of the array to be sorted * @ArrayType(T) * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed */ public static GENERIC_KEY_BRACES void parallelQuickSort(KEY_TYPE[] array, int length) { parallelQuickSort(array, 0, length); } /** * Sorts an array according to the natural ascending order using Parallel Quick Sort, * This implementation is a custom of FastUtil quicksort but with a different code structure, * and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993. * @param array the array that needs to be sorted * @param from where the array should be sorted from * @param to where the array should be sorted to * @ArrayType(T) * @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed */ public static GENERIC_KEY_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); } static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to) { KEY_TYPE t = a[from]; a[from] = a[to]; a[to] = t; } static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, int length) { to -= length; for(int i = 0;i 0 ? b : comp.compare(data[a], data[c]) > 0 ? c : a); } static GENERIC_KEY_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length) { return medium(data, medium(data, a, a + length, a + (length * 2)), medium(data, b - length, b, b + length), medium(data, c - (length * 2), c - length, c)); } static GENERIC_KEY_BRACES int medium(KEY_TYPE[] data, int a, int b, int c) { return COMPAREABLE_TO_KEY(data[a], data[b]) < 0 ? (COMPAREABLE_TO_KEY(data[b], data[c]) < 0 ? b : COMPAREABLE_TO_KEY(data[a], data[c]) < 0 ? c : a) : (COMPAREABLE_TO_KEY(data[b], data[c]) > 0 ? b : COMPAREABLE_TO_KEY(data[a], data[c]) > 0 ? c : a); } static class QuickSortAction KEY_GENERIC_TYPE extends RecursiveAction { private static final long serialVersionUID = 0L; KEY_TYPE[] array; int from; int to; QuickSortAction(KEY_TYPE[] array, int from, int to) { this.array = array; this.from = from; this.to = to; } @Override protected void compute() { int length = to - from; if(length <= 0) return; if(length < BASE_THRESHOLD) { selectionSort(array, from, to); return; } KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8) : medium(array, from, from + (length / 2), to - 1)]; int a = from, b = a, c = to - 1, d = c; for(int comp = 0;;swap(array, b++, c--)) { for(;b<=c && (comp = COMPAREABLE_TO_KEY(array[b], pivot)) <= 0;b++) { if(comp == 0) swap(array, a++, b); } for(;c>=b && (comp = COMPAREABLE_TO_KEY(array[c], pivot)) >= 0;c--) { if(comp == 0) swap(array, c, d--); } if(b>c) break; } swap(array, from, b, Math.min(a - from, b - a)); swap(array, b, to, Math.min(d - c, to - d - 1)); if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionBRACES(array, from, from + (b - a)), new QuickSortActionBRACES(array, to - (d - c), to)); else if(b - a > 1) new QuickSortActionBRACES(array, from, from + (b - a)).invoke(); else if(d - c > 1) new QuickSortActionBRACES(array, to - (d - c), to).invoke(); } } static class QuickSortActionComp KEY_GENERIC_TYPE extends RecursiveAction { private static final long serialVersionUID = 0L; KEY_TYPE[] array; int from; int to; COMPARATOR KEY_GENERIC_TYPE comp; QuickSortActionComp(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() { int length = to - from; if(length <= 0) return; if(length < BASE_THRESHOLD) { selectionSort(array, from, to, comp); return; } KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)]; int a = from, b = a, c = to - 1, d = c; for(int compare;;swap(array, b++, c--)) { for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) { if(compare == 0) swap(array, a++, b); } for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) { if(compare == 0) swap(array, c, d--); } if(b>c) break; } swap(array, from, b, Math.min(a - from, b - a)); swap(array, b, to, Math.min(d - c, to - d - 1)); if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompBRACES(array, from, from + (b - a), comp), new QuickSortActionCompBRACES(array, to - (d - c), to, comp)); else if(b - a > 1) new QuickSortActionCompBRACES(array, from, from + (b - a), comp).invoke(); else if(d - c > 1) new QuickSortActionCompBRACES(array, to - (d - c), to, comp).invoke(); } } static class MergeSortAction KEY_GENERIC_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(COMPAREABLE_TO_KEY(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 && COMPAREABLE_TO_KEY(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_GENERIC_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(COMPAREABLE_TO_KEY(array[mid - 1], array[mid]) <= 0) return; for(int i = from, j = mid, comp;i < j && j < to;) { if((comp = COMPAREABLE_TO_KEY(array[i], array[j])) < 0) i++; else if(comp == 0) swap(array, ++i, j); else { int k = j; for(;k < to - 1 && COMPAREABLE_TO_KEY(array[i], array[k + 1]) > 0;k++); if(j == k) { swap(array, i++, j); continue; } else if(j + 1 == k) { KEY_TYPE value = array[j]; System.arraycopy(array, i, array, i+1, j - i); array[i] = value; i++; j++; continue; } KEY_TYPE[] data = NEW_KEY_ARRAY(k - j); System.arraycopy(array, j, data, 0, data.length); System.arraycopy(array, i, array, i+data.length, j - i); System.arraycopy(data, 0, array, i, data.length); i+=data.length; j+=data.length; } } } } 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 { int k = j; for(;k < to - 1 && comp.compare(array[i], array[k + 1]) > 0;k++); if(j == k) { swap(array, i++, j); continue; } else if(j + 1 == k) { KEY_TYPE value = array[j]; System.arraycopy(array, i, array, i+1, j - i); array[i] = value; i++; j++; continue; } KEY_TYPE[] data = NEW_KEY_ARRAY(k - j); System.arraycopy(array, j, data, 0, data.length); System.arraycopy(array, i, array, i+data.length, j - i); System.arraycopy(data, 0, array, i, data.length); i+=data.length; j+=data.length; } } } } }