Sync with latest changes
This commit is contained in:
+1
-1
@@ -48,7 +48,7 @@ dependencies {
|
||||
builderImplementation 'com.google.code.gson:gson:2.10'
|
||||
builderImplementation 'de.speiger:Simple-Code-Generator:1.3.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'com.google.guava:guava-testlib:31.0.1-jre'
|
||||
testImplementation 'com.google.guava:guava-testlib:33.6.0-jre'
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ public class MapModule extends BaseModule
|
||||
public static final FunctionDependency ENUM_MAP = MODULE.createDependency("EnumMap").addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency LINKED_ENUM_MAP = MODULE.createDependency("LinkedEnumMap").addEntryDependency(ENUM_MAP).addEntryDependency(ORDERED_MAP);
|
||||
|
||||
public static final FunctionDependency REF_MAP = MODULE.createDependency("ReferenceHashMap").addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency LINKED_REF_MAP = MODULE.createDependency("LinkedReferenceMap").addEntryDependency(REF_MAP).addEntryDependency(ORDERED_MAP);
|
||||
|
||||
|
||||
public static final FunctionDependency CONCURRENT_MAP = MODULE.createDependency("ConcurrentMap").addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency AVL_TREE_MAP = MODULE.createDependency("AVLTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency RB_TREE_MAP = MODULE.createDependency("RBTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
|
||||
@@ -51,7 +55,7 @@ public class MapModule extends BaseModule
|
||||
@Override
|
||||
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
|
||||
List<IDependency> dependencies = new ArrayList<>(Arrays.asList(MODULE, ORDERED_MAP, SORTED_MAP, IMPLEMENTATION, WRAPPERS, ARRAY_MAP, IMMUTABLE_MAP, HASH_MAP, LINKED_MAP, CUSTOM_MAP, LINKED_CUSTOM_MAP, CONCURRENT_MAP, AVL_TREE_MAP, RB_TREE_MAP));
|
||||
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP));
|
||||
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP, REF_MAP, LINKED_REF_MAP));
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@@ -70,6 +74,10 @@ public class MapModule extends BaseModule
|
||||
if(AVL_TREE_MAP.isEnabled()) addFlag("AVL_TREE_MAP_FEATURE");
|
||||
if(RB_TREE_MAP.isEnabled()) addFlag("RB_TREE_MAP_FEATURE");
|
||||
|
||||
if(REF_MAP.isEnabled()) addFlag("REF_MAP_FEATURE");
|
||||
if(LINKED_REF_MAP.isEnabled()) addFlag("LINKED_REF_MAP_FEATURE");
|
||||
|
||||
|
||||
if(CONCURRENT_MAP.isEnabled()) addFlag("CONCURRENT_MAP_FEATURE");
|
||||
if(IMMUTABLE_MAP.isEnabled()) addFlag("IMMUTABLE_MAP_FEATURE");
|
||||
if(HASH_MAP.isEnabled()) addFlag("MAP_FEATURE");
|
||||
@@ -85,6 +93,8 @@ public class MapModule extends BaseModule
|
||||
if(!IMMUTABLE_MAP.isEnabled()) addBlockedFiles("ImmutableOpenHashMap");
|
||||
if(!CONCURRENT_MAP.isEnabled()) addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap");
|
||||
if(!ORDERED_MAP.isEnabled()) addBlockedFiles("OrderedMap");
|
||||
if(!REF_MAP.isEnabled()) addBlockedFiles("ReferenceHashMap");
|
||||
if(!LINKED_REF_MAP.isEnabled()) addBlockedFiles("LinkedReferenceHashMap");
|
||||
if(!HASH_MAP.isEnabled()) addBlockedFiles("OpenHashMap");
|
||||
if(!LINKED_MAP.isEnabled()) addBlockedFiles("LinkedOpenHashMap");
|
||||
if(!CUSTOM_MAP.isEnabled()) addBlockedFiles("OpenCustomHashMap");
|
||||
@@ -127,6 +137,8 @@ public class MapModule extends BaseModule
|
||||
addBiRequirement("AbstractMap");
|
||||
addEnumRequirement("EnumMap");
|
||||
addEnumRequirement("LinkedEnumMap");
|
||||
addEnumRequirement("ReferenceHashMap");
|
||||
addEnumRequirement("LinkedReferenceHashMap");
|
||||
addBiRequirement("ConcurrentOpenHashMap");
|
||||
addBiRequirement("ImmutableOpenHashMap");
|
||||
addBiRequirement("OpenHashMap");
|
||||
@@ -141,6 +153,8 @@ public class MapModule extends BaseModule
|
||||
addRemapper("AbstractMap", "Abstract%sMap");
|
||||
addRemapper("EnumMap", "Enum2%sMap");
|
||||
addRemapper("LinkedEnumMap", "LinkedEnum2%sMap");
|
||||
addRemapper("ReferenceHashMap", "Reference2%sHashMap");
|
||||
addRemapper("LinkedReferenceHashMap", "Reference2%sLinkedHashMap");
|
||||
addRemapper("ImmutableOpenHashMap", "Immutable%sOpenHashMap");
|
||||
|
||||
//Test Classes
|
||||
@@ -249,6 +263,8 @@ public class MapModule extends BaseModule
|
||||
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
|
||||
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
|
||||
addFunctionValueMappers("ENUM_MAP", valueType.isObject() ? "Enum2ObjectMap" : "Enum2%sMap");
|
||||
addFunctionValueMappers("REF_MAP", valueType.isObject() ? "Reference2ObjectHashMap" : "Reference2%sHashMap");
|
||||
addFunctionValueMappers("LINKED_REF_MAP", valueType.isObject() ? "Reference2ObjectLinkedHashMap" : "Reference2%sLinkedHashMap");
|
||||
addBiClassMapper("HASH_MAP", "OpenHashMap", "2");
|
||||
addBiClassMapper("ARRAY_MAP", "ArrayMap", "2");
|
||||
|
||||
|
||||
+2
-2
@@ -288,7 +288,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
|
||||
while(KEY_EQUALS_NULL(key)) {
|
||||
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
|
||||
if(KEY_EQUALS(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -312,7 +312,7 @@ public class LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE extends HASH_MAP KEY_VALUE_G
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(KEY_TO_HASH(key)) & mask;
|
||||
while(KEY_EQUALS_NULL(key)) {
|
||||
while(KEY_EQUALS_NOT_NULL(keys[pos])) {
|
||||
if(KEY_EQUALS(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+1581
File diff suppressed because it is too large
Load Diff
+1572
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@ import java.util.function.IntFunction;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -337,6 +338,69 @@ public class ARRAYS
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, RANDOM random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, int length, RANDOM random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, int offset, int length, RANDOM random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
KEY_TYPE t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -575,6 +639,55 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectInsertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectInsertionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectInsertionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
KEY_TYPE current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -661,6 +774,60 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectSelectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectSelectionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectSelectionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
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
|
||||
@@ -760,6 +927,72 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -856,6 +1089,56 @@ public class ARRAYS
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @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 indirectParallelMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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 indirectParallelMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @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 indirectParallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwapBRACES(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1209,6 +1492,73 @@ public class ARRAYS
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1313,6 +1663,58 @@ public class ARRAYS
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @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 indirectParallelQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @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 indirectParallelQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @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 indirectParallelQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwapBRACES(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1367,6 +1769,18 @@ public class ARRAYS
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, 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, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static GENERIC_KEY_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1389,16 +1803,14 @@ public class ARRAYS
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(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()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1431,8 +1843,7 @@ public class ARRAYS
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
|
||||
QuickSortActionComp(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;
|
||||
@@ -1440,8 +1851,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1467,6 +1877,49 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap KEY_GENERIC_TYPE extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
KEY_TYPE[] array;
|
||||
int from;
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwapBRACES(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwapBRACES(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwapBRACES(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwapBRACES(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
KEY_TYPE[] array;
|
||||
@@ -1474,8 +1927,7 @@ public class ARRAYS
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(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;
|
||||
@@ -1483,8 +1935,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1512,8 +1963,7 @@ public class ARRAYS
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
|
||||
MergeSortActionComp(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;
|
||||
@@ -1522,8 +1972,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1543,22 +1992,64 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap 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;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwapBRACES(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwapBRACES(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
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)
|
||||
{
|
||||
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1604,8 +2095,7 @@ public class ARRAYS
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
|
||||
MemFreeMergeSortActionComp(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;
|
||||
@@ -1613,8 +2103,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+93
@@ -27,6 +27,8 @@ import speiger.src.collections.PACKAGE.maps.impl.concurrent.CONCURRENT_HASH_MAP;
|
||||
#if TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.REF_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.LINKED_REF_MAP;
|
||||
#endif
|
||||
|
||||
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
|
||||
@@ -134,6 +136,97 @@ public class MAP_CONSTRUCTOR_TESTS
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
public static class RefMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester KEY_VALUE_STRING_GENERIC_TYPE
|
||||
{
|
||||
public RefMap() {
|
||||
setSimpleConstructor(REF_MAP::new);
|
||||
setSizeConstructor(REF_MAP::new);
|
||||
setPArrayConstructor(REF_MAP::new);
|
||||
#if !TYPE_OBJECT || !VALUE_OBJECT
|
||||
setArrayConstructor(REF_MAP::new);
|
||||
#endif
|
||||
setPMapConstructor(REF_MAP::new);
|
||||
setMapConstructor(REF_MAP::new);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongLoadFactorSize() {
|
||||
setSizeConstructor(T -> new REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 0F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 0 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {}
|
||||
|
||||
setSizeConstructor(T -> new REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 1F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 1 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {}
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@Override
|
||||
protected String[] createKeyElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 0, 100);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
@Override
|
||||
protected String[] createValueElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 100, 200);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
public static class LinkedRefMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester KEY_VALUE_STRING_GENERIC_TYPE
|
||||
{
|
||||
public LinkedRefMap() {
|
||||
setSimpleConstructor(LINKED_REF_MAP::new);
|
||||
setSizeConstructor(LINKED_REF_MAP::new);
|
||||
setPArrayConstructor(LINKED_REF_MAP::new);
|
||||
#if !TYPE_OBJECT || !VALUE_OBJECT
|
||||
setArrayConstructor(LINKED_REF_MAP::new);
|
||||
#endif
|
||||
setPMapConstructor(LINKED_REF_MAP::new);
|
||||
setMapConstructor(LINKED_REF_MAP::new);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongLoadFactorSize() {
|
||||
setSizeConstructor(T -> new LINKED_REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 0F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 0 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {
|
||||
}
|
||||
|
||||
setSizeConstructor(T -> new LINKED_REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 1F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 1 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {
|
||||
}
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@Override
|
||||
protected String[] createKeyElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 0, 100);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
@Override
|
||||
protected String[] createValueElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 100, 200);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if VALUE_OBJECT
|
||||
public static class EnumMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester<AnEnum, String>
|
||||
#else
|
||||
|
||||
@@ -41,6 +41,8 @@ import speiger.src.collections.PACKAGE.maps.impl.misc.ARRAY_MAP;
|
||||
#if TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.REF_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.LINKED_REF_MAP;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.maps.impl.tree.AVL_TREE_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
|
||||
@@ -104,6 +106,7 @@ public class MAP_TESTS extends TestCase
|
||||
#if TYPE_OBJECT
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.EnumMap.class));
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.LinkedEnumMap.class));
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.RefMap.class));
|
||||
#endif
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.CustomHashMap.class));
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.LinkedCustomHashMap.class));
|
||||
@@ -130,27 +133,29 @@ public class MAP_TESTS extends TestCase
|
||||
}
|
||||
|
||||
public static void suite(TestSuite suite) {
|
||||
suite.addTest(mapSuite("HASH_MAP", HASH_MAP::new, getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_HASH_MAP", LINKED_HASH_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("IMMUTABLE_HASH_MAP", IMMUTABLE_HASH_MAP::new, getImmutableFeatures(), -1));
|
||||
suite.addTest(mapSuite("HASH_MAP", HASH_MAP::new, getFeatures(), -1, true, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_HASH_MAP", LINKED_HASH_MAP::new, getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("IMMUTABLE_HASH_MAP", IMMUTABLE_HASH_MAP::new, getImmutableFeatures(), -1, true));
|
||||
#if TYPE_OBJECT
|
||||
suite.addTest(enumMapSuite("ENUM_MAP", ENUM_MAP::new, getFeatures(), 5));
|
||||
suite.addTest(enumOrderedMapSuite("LINKED_ENUM_MAP", (K, V) -> K.length <= 0 ? new LINKED_ENUM_MAP<>(AnEnum.class) : new LINKED_ENUM_MAP<>(K, V), getFeatures(), 5));
|
||||
suite.addTest(mapSuite("REF_MAP", REF_MAP::new, getFeatures(), - 1, true, false));
|
||||
suite.addTest(orderedMapSuite("LINKED_REF_MAP", LINKED_REF_MAP::new, getFeatures(), - 1, false));
|
||||
#endif
|
||||
suite.addTest(mapSuite("CUSTOM_HASH_MAP", (K, V) -> new CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_CUSTOM_HASH_MAP", (K, V) -> new LINKED_CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("ARRAY_MAP", ARRAY_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(mapSuite("CUSTOM_HASH_MAP", (K, V) -> new CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_CUSTOM_HASH_MAP", (K, V) -> new LINKED_CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("ARRAY_MAP", ARRAY_MAP::new, getFeatures(), -1, true));
|
||||
suite.addTest(concurrentMapSuite("CONCURRENT_HASH_MAP", CONCURRENT_HASH_MAP::new, getFeatures(), 2));
|
||||
suite.addTest(concurrentMapSuite("CONCURRENT_HASH_MAP", CONCURRENT_HASH_MAP::new, getFeatures(), 3));
|
||||
suite.addTest(navigableMapSuite("RB_TREE_MAP", RB_TREE_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(navigableMapSuite("AVL_TREE_MAP", AVL_TREE_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(navigableMapSuite("SynchronizedRB_TREE_MAP", (K, V) -> new RB_TREE_MAPKV_BRACES(K, V).synchronize(), getLimitedFeatures(), -1));
|
||||
suite.addTest(navigableMapSuite("UnmodifiableRB_TREE_MAP", (K, V) -> new RB_TREE_MAPKV_BRACES(K, V).unmodifiable(), getLimitedImmutableFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("SynchronizedORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).synchronize(), getFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("UnmodifiableORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).unmodifiable(), getImmutableFeatures(), -1));
|
||||
suite.addTest(mapSuite("EmptyMAP", (K, V) -> MAPS.empty(), getEmptyFeatures(), 0, false));
|
||||
suite.addTest(mapSuite("SingletonMAP", (K, V) -> MAPS.singleton(K[0], V[0]), getEmptyFeatures(), 1, false));
|
||||
suite.addTest(mapSuite("AbstractMap", SIMPLE_TEST_MAP::new, getTestFeatures(), -1, false));
|
||||
suite.addTest(orderedMapSuite("SynchronizedORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).synchronize(), getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("UnmodifiableORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).unmodifiable(), getImmutableFeatures(), -1, true));
|
||||
suite.addTest(mapSuite("EmptyMAP", (K, V) -> MAPS.empty(), getEmptyFeatures(), 0, false, true));
|
||||
suite.addTest(mapSuite("SingletonMAP", (K, V) -> MAPS.singleton(K[0], V[0]), getEmptyFeatures(), 1, false, true));
|
||||
suite.addTest(mapSuite("AbstractMap", SIMPLE_TEST_MAP::new, getTestFeatures(), -1, false, true));
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@@ -209,14 +214,14 @@ public class MAP_TESTS extends TestCase
|
||||
|
||||
#endif
|
||||
|
||||
private static Test mapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean sorted) {
|
||||
private static Test mapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean sorted, boolean allowNullKeys) {
|
||||
SIMPLE_MAP_TEST_GENERATOR.Maps KEY_VALUE_STRING_GENERIC_TYPE generator = new SIMPLE_MAP_TEST_GENERATOR.Maps KEY_VALUE_STRING_GENERIC_TYPE(factory);
|
||||
MAP_TEST_BUILDER KEY_VALUE_STRING_GENERIC_TYPE builder = MAP_TEST_BUILDER.using(generator);
|
||||
builder.shouldBlockKeys(sorted);
|
||||
#if TYPE_OBJECT
|
||||
generator.setKeys(createKeys());
|
||||
#ignore
|
||||
builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
if(allowNullKeys) builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
#endignore
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
@@ -265,13 +270,13 @@ public class MAP_TESTS extends TestCase
|
||||
return builder.named(name).createTestSuite();
|
||||
}
|
||||
|
||||
private static Test orderedMapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], ORDERED_MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size) {
|
||||
private static Test orderedMapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], ORDERED_MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean allowNullKeys) {
|
||||
SIMPLE_MAP_TEST_GENERATOR.OrderedMaps KEY_VALUE_STRING_GENERIC_TYPE generator = new SIMPLE_MAP_TEST_GENERATOR.OrderedMaps KEY_VALUE_STRING_GENERIC_TYPE(factory);
|
||||
ORDERED_MAP_TEST_BUILDER KEY_VALUE_STRING_GENERIC_TYPE builder = ORDERED_MAP_TEST_BUILDER.using(generator);
|
||||
#if TYPE_OBJECT
|
||||
generator.setKeys(createKeys());
|
||||
#ignore
|
||||
builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
if(allowNullKeys) builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
#endignore
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.booleans.functions.BooleanComparator;
|
||||
import speiger.src.collections.booleans.collections.BooleanIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class BooleanArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
boolean t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectInsertionSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
boolean current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectSelectionSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
boolean 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
boolean 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
|
||||
@@ -662,6 +819,69 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectMergeSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class BooleanArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class BooleanArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectQuickSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
boolean 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class BooleanArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class BooleanArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(boolean[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
boolean t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(boolean[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(boolean[] data, int a, int b, int c, int length, BooleanComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class BooleanArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(boolean[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(boolean[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class BooleanArrays
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
|
||||
QuickSortActionComp(boolean[] array, int from, int to, BooleanComparator comp)
|
||||
{
|
||||
QuickSortActionComp(boolean[] array, int from, int to, BooleanComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
int from;
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
boolean 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class BooleanArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(boolean[] array, boolean[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(boolean[] array, boolean[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class BooleanArrays
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
|
||||
MergeSortActionComp(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp)
|
||||
{
|
||||
MergeSortActionComp(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
boolean[] supp;
|
||||
int from;
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(boolean[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(boolean[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class BooleanArrays
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(boolean[] array, int from, int to, BooleanComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(boolean[] array, int from, int to, BooleanComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2BooleanLinkedOpenHashMap extends Byte2BooleanOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2BooleanLinkedOpenHashMap extends Byte2BooleanOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -241,7 +241,7 @@ public class Byte2ByteLinkedOpenHashMap extends Byte2ByteOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class Byte2ByteLinkedOpenHashMap extends Byte2ByteOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2CharLinkedOpenHashMap extends Byte2CharOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2CharLinkedOpenHashMap extends Byte2CharOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2DoubleLinkedOpenHashMap extends Byte2DoubleOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2DoubleLinkedOpenHashMap extends Byte2DoubleOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2FloatLinkedOpenHashMap extends Byte2FloatOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2FloatLinkedOpenHashMap extends Byte2FloatOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2IntLinkedOpenHashMap extends Byte2IntOpenHashMap implements By
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2IntLinkedOpenHashMap extends Byte2IntOpenHashMap implements By
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2LongLinkedOpenHashMap extends Byte2LongOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2LongLinkedOpenHashMap extends Byte2LongOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ public class Byte2ObjectLinkedOpenHashMap<V> extends Byte2ObjectOpenHashMap<V> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class Byte2ObjectLinkedOpenHashMap<V> extends Byte2ObjectOpenHashMap<V> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Byte2ShortLinkedOpenHashMap extends Byte2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Byte2ShortLinkedOpenHashMap extends Byte2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.bytes.functions.ByteComparator;
|
||||
import speiger.src.collections.bytes.collections.ByteIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class ByteArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
byte t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectInsertionSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
byte current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectSelectionSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
byte 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
byte 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
|
||||
@@ -662,6 +819,69 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectMergeSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(byte[] array, byte[] supp, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class ByteArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(byte[] array, byte[] supp, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class ByteArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectQuickSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
byte 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class ByteArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class ByteArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(byte[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
byte t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(byte[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(byte[] data, int a, int b, int c, int length, ByteComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class ByteArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(byte[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(byte[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class ByteArrays
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
|
||||
QuickSortActionComp(byte[] array, int from, int to, ByteComparator comp)
|
||||
{
|
||||
QuickSortActionComp(byte[] array, int from, int to, ByteComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
int from;
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
byte 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class ByteArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(byte[] array, byte[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(byte[] array, byte[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class ByteArrays
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
|
||||
MergeSortActionComp(byte[] array, byte[] supp, int from, int to, ByteComparator comp)
|
||||
{
|
||||
MergeSortActionComp(byte[] array, byte[] supp, int from, int to, ByteComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
byte[] supp;
|
||||
int from;
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(byte[] array, byte[] supp, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(byte[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(byte[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class ByteArrays
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(byte[] array, int from, int to, ByteComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(byte[] array, int from, int to, ByteComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2BooleanLinkedOpenHashMap extends Char2BooleanOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2BooleanLinkedOpenHashMap extends Char2BooleanOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2ByteLinkedOpenHashMap extends Char2ByteOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2ByteLinkedOpenHashMap extends Char2ByteOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -241,7 +241,7 @@ public class Char2CharLinkedOpenHashMap extends Char2CharOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class Char2CharLinkedOpenHashMap extends Char2CharOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2DoubleLinkedOpenHashMap extends Char2DoubleOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2DoubleLinkedOpenHashMap extends Char2DoubleOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2FloatLinkedOpenHashMap extends Char2FloatOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2FloatLinkedOpenHashMap extends Char2FloatOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2IntLinkedOpenHashMap extends Char2IntOpenHashMap implements Ch
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2IntLinkedOpenHashMap extends Char2IntOpenHashMap implements Ch
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2LongLinkedOpenHashMap extends Char2LongOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2LongLinkedOpenHashMap extends Char2LongOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ public class Char2ObjectLinkedOpenHashMap<V> extends Char2ObjectOpenHashMap<V> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class Char2ObjectLinkedOpenHashMap<V> extends Char2ObjectOpenHashMap<V> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Char2ShortLinkedOpenHashMap extends Char2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Char2ShortLinkedOpenHashMap extends Char2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.chars.functions.CharComparator;
|
||||
import speiger.src.collections.chars.collections.CharIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class CharArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
char t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectInsertionSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
char current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectSelectionSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
char 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
char 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
|
||||
@@ -662,6 +819,69 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectMergeSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(char[] array, char[] supp, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class CharArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(char[] array, char[] supp, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class CharArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectQuickSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
char 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class CharArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class CharArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(char[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
char t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(char[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(char[] data, int a, int b, int c, int length, CharComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class CharArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(char[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(char[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class CharArrays
|
||||
int to;
|
||||
CharComparator comp;
|
||||
|
||||
QuickSortActionComp(char[] array, int from, int to, CharComparator comp)
|
||||
{
|
||||
QuickSortActionComp(char[] array, int from, int to, CharComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
int from;
|
||||
int to;
|
||||
CharComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
char 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class CharArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(char[] array, char[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(char[] array, char[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class CharArrays
|
||||
int to;
|
||||
CharComparator comp;
|
||||
|
||||
MergeSortActionComp(char[] array, char[] supp, int from, int to, CharComparator comp)
|
||||
{
|
||||
MergeSortActionComp(char[] array, char[] supp, int from, int to, CharComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
char[] supp;
|
||||
int from;
|
||||
int to;
|
||||
CharComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(char[] array, char[] supp, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(char[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(char[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class CharArrays
|
||||
int to;
|
||||
CharComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(char[] array, int from, int to, CharComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(char[] array, int from, int to, CharComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2BooleanLinkedOpenHashMap extends Double2BooleanOpenHashMap i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2BooleanLinkedOpenHashMap extends Double2BooleanOpenHashMap i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2ByteLinkedOpenHashMap extends Double2ByteOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2ByteLinkedOpenHashMap extends Double2ByteOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2CharLinkedOpenHashMap extends Double2CharOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2CharLinkedOpenHashMap extends Double2CharOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -241,7 +241,7 @@ public class Double2DoubleLinkedOpenHashMap extends Double2DoubleOpenHashMap imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class Double2DoubleLinkedOpenHashMap extends Double2DoubleOpenHashMap imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2FloatLinkedOpenHashMap extends Double2FloatOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2FloatLinkedOpenHashMap extends Double2FloatOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2IntLinkedOpenHashMap extends Double2IntOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2IntLinkedOpenHashMap extends Double2IntOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2LongLinkedOpenHashMap extends Double2LongOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2LongLinkedOpenHashMap extends Double2LongOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ public class Double2ObjectLinkedOpenHashMap<V> extends Double2ObjectOpenHashMap<
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class Double2ObjectLinkedOpenHashMap<V> extends Double2ObjectOpenHashMap<
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Double2ShortLinkedOpenHashMap extends Double2ShortOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Double2ShortLinkedOpenHashMap extends Double2ShortOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.doubles.functions.DoubleComparator;
|
||||
import speiger.src.collections.doubles.collections.DoubleIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class DoubleArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
double t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectInsertionSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
double current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectSelectionSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
double 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
double 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
|
||||
@@ -662,6 +819,69 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectMergeSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(double[] array, double[] supp, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class DoubleArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(double[] array, double[] supp, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class DoubleArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectQuickSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
double 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class DoubleArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class DoubleArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(double[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
double t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(double[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(double[] data, int a, int b, int c, int length, DoubleComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class DoubleArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(double[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(double[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class DoubleArrays
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
|
||||
QuickSortActionComp(double[] array, int from, int to, DoubleComparator comp)
|
||||
{
|
||||
QuickSortActionComp(double[] array, int from, int to, DoubleComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
int from;
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
double 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class DoubleArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(double[] array, double[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(double[] array, double[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class DoubleArrays
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
|
||||
MergeSortActionComp(double[] array, double[] supp, int from, int to, DoubleComparator comp)
|
||||
{
|
||||
MergeSortActionComp(double[] array, double[] supp, int from, int to, DoubleComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
double[] supp;
|
||||
int from;
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(double[] array, double[] supp, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(double[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(double[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class DoubleArrays
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(double[] array, int from, int to, DoubleComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(double[] array, int from, int to, DoubleComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2BooleanLinkedOpenHashMap extends Float2BooleanOpenHashMap imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2BooleanLinkedOpenHashMap extends Float2BooleanOpenHashMap imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2ByteLinkedOpenHashMap extends Float2ByteOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2ByteLinkedOpenHashMap extends Float2ByteOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2CharLinkedOpenHashMap extends Float2CharOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2CharLinkedOpenHashMap extends Float2CharOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2DoubleLinkedOpenHashMap extends Float2DoubleOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2DoubleLinkedOpenHashMap extends Float2DoubleOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -241,7 +241,7 @@ public class Float2FloatLinkedOpenHashMap extends Float2FloatOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class Float2FloatLinkedOpenHashMap extends Float2FloatOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2IntLinkedOpenHashMap extends Float2IntOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2IntLinkedOpenHashMap extends Float2IntOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2LongLinkedOpenHashMap extends Float2LongOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2LongLinkedOpenHashMap extends Float2LongOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ public class Float2ObjectLinkedOpenHashMap<V> extends Float2ObjectOpenHashMap<V>
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class Float2ObjectLinkedOpenHashMap<V> extends Float2ObjectOpenHashMap<V>
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Float2ShortLinkedOpenHashMap extends Float2ShortOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Float2ShortLinkedOpenHashMap extends Float2ShortOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.floats.functions.FloatComparator;
|
||||
import speiger.src.collections.floats.collections.FloatIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class FloatArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
float t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectInsertionSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
float current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectSelectionSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
float 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
float 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
|
||||
@@ -662,6 +819,69 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectMergeSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(float[] array, float[] supp, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class FloatArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(float[] array, float[] supp, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class FloatArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectQuickSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
float 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class FloatArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class FloatArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(float[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
float t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(float[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(float[] data, int a, int b, int c, int length, FloatComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class FloatArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(float[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(float[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class FloatArrays
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
|
||||
QuickSortActionComp(float[] array, int from, int to, FloatComparator comp)
|
||||
{
|
||||
QuickSortActionComp(float[] array, int from, int to, FloatComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
int from;
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
float 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class FloatArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(float[] array, float[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(float[] array, float[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class FloatArrays
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
|
||||
MergeSortActionComp(float[] array, float[] supp, int from, int to, FloatComparator comp)
|
||||
{
|
||||
MergeSortActionComp(float[] array, float[] supp, int from, int to, FloatComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
float[] supp;
|
||||
int from;
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(float[] array, float[] supp, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(float[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(float[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class FloatArrays
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(float[] array, int from, int to, FloatComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(float[] array, int from, int to, FloatComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2BooleanLinkedOpenHashMap extends Int2BooleanOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2BooleanLinkedOpenHashMap extends Int2BooleanOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2ByteLinkedOpenHashMap extends Int2ByteOpenHashMap implements In
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2ByteLinkedOpenHashMap extends Int2ByteOpenHashMap implements In
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2CharLinkedOpenHashMap extends Int2CharOpenHashMap implements In
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2CharLinkedOpenHashMap extends Int2CharOpenHashMap implements In
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2DoubleLinkedOpenHashMap extends Int2DoubleOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2DoubleLinkedOpenHashMap extends Int2DoubleOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2FloatLinkedOpenHashMap extends Int2FloatOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2FloatLinkedOpenHashMap extends Int2FloatOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -240,7 +240,7 @@ public class Int2IntLinkedOpenHashMap extends Int2IntOpenHashMap implements Int2
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -264,7 +264,7 @@ public class Int2IntLinkedOpenHashMap extends Int2IntOpenHashMap implements Int2
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2LongLinkedOpenHashMap extends Int2LongOpenHashMap implements In
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2LongLinkedOpenHashMap extends Int2LongOpenHashMap implements In
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -242,7 +242,7 @@ public class Int2ObjectLinkedOpenHashMap<V> extends Int2ObjectOpenHashMap<V> imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -266,7 +266,7 @@ public class Int2ObjectLinkedOpenHashMap<V> extends Int2ObjectOpenHashMap<V> imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -248,7 +248,7 @@ public class Int2ShortLinkedOpenHashMap extends Int2ShortOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public class Int2ShortLinkedOpenHashMap extends Int2ShortOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.ints.functions.IntComparator;
|
||||
import speiger.src.collections.ints.collections.IntIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class IntArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
int t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectInsertionSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
int current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectSelectionSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
int 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
int 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
|
||||
@@ -662,6 +819,69 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectMergeSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(int[] array, int[] supp, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class IntArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(int[] array, int[] supp, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class IntArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectQuickSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
int 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class IntArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class IntArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(int[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
int t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(int[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(int[] data, int a, int b, int c, int length, IntComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class IntArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(int[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(int[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class IntArrays
|
||||
int to;
|
||||
IntComparator comp;
|
||||
|
||||
QuickSortActionComp(int[] array, int from, int to, IntComparator comp)
|
||||
{
|
||||
QuickSortActionComp(int[] array, int from, int to, IntComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
int from;
|
||||
int to;
|
||||
IntComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
int 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class IntArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(int[] array, int[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(int[] array, int[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class IntArrays
|
||||
int to;
|
||||
IntComparator comp;
|
||||
|
||||
MergeSortActionComp(int[] array, int[] supp, int from, int to, IntComparator comp)
|
||||
{
|
||||
MergeSortActionComp(int[] array, int[] supp, int from, int to, IntComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
int[] supp;
|
||||
int from;
|
||||
int to;
|
||||
IntComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(int[] array, int[] supp, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(int[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(int[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class IntArrays
|
||||
int to;
|
||||
IntComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(int[] array, int from, int to, IntComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(int[] array, int from, int to, IntComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2BooleanLinkedOpenHashMap extends Long2BooleanOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2BooleanLinkedOpenHashMap extends Long2BooleanOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2ByteLinkedOpenHashMap extends Long2ByteOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2ByteLinkedOpenHashMap extends Long2ByteOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2CharLinkedOpenHashMap extends Long2CharOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2CharLinkedOpenHashMap extends Long2CharOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2DoubleLinkedOpenHashMap extends Long2DoubleOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2DoubleLinkedOpenHashMap extends Long2DoubleOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2FloatLinkedOpenHashMap extends Long2FloatOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2FloatLinkedOpenHashMap extends Long2FloatOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2IntLinkedOpenHashMap extends Long2IntOpenHashMap implements Lo
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2IntLinkedOpenHashMap extends Long2IntOpenHashMap implements Lo
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -241,7 +241,7 @@ public class Long2LongLinkedOpenHashMap extends Long2LongOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class Long2LongLinkedOpenHashMap extends Long2LongOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -243,7 +243,7 @@ public class Long2ObjectLinkedOpenHashMap<V> extends Long2ObjectOpenHashMap<V> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class Long2ObjectLinkedOpenHashMap<V> extends Long2ObjectOpenHashMap<V> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Long2ShortLinkedOpenHashMap extends Long2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Long2ShortLinkedOpenHashMap extends Long2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.longs.functions.LongComparator;
|
||||
import speiger.src.collections.longs.collections.LongIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -269,6 +270,65 @@ public class LongArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
long t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -489,6 +549,52 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectInsertionSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
long current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -569,6 +675,57 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectSelectionSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
long 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
long 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
|
||||
@@ -662,6 +819,69 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectMergeSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(long[] array, long[] supp, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -752,6 +972,53 @@ public class LongArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
*/
|
||||
public static void indirectParallelMergeSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(long[] array, long[] supp, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1087,6 +1354,70 @@ public class LongArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectQuickSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
long 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1185,6 +1516,55 @@ public class LongArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1236,6 +1616,18 @@ public class LongArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(long[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
long t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(long[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(long[] data, int a, int b, int c, int length, LongComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1258,16 +1650,14 @@ public class LongArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(long[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(long[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1300,8 +1690,7 @@ public class LongArrays
|
||||
int to;
|
||||
LongComparator comp;
|
||||
|
||||
QuickSortActionComp(long[] array, int from, int to, LongComparator comp)
|
||||
{
|
||||
QuickSortActionComp(long[] array, int from, int to, LongComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1309,8 +1698,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1336,6 +1724,49 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
int from;
|
||||
int to;
|
||||
LongComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
long 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
@@ -1343,8 +1774,7 @@ public class LongArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(long[] array, long[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(long[] array, long[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1352,8 +1782,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1381,8 +1810,7 @@ public class LongArrays
|
||||
int to;
|
||||
LongComparator comp;
|
||||
|
||||
MergeSortActionComp(long[] array, long[] supp, int from, int to, LongComparator comp)
|
||||
{
|
||||
MergeSortActionComp(long[] array, long[] supp, int from, int to, LongComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1391,8 +1819,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1412,22 +1839,64 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
long[] supp;
|
||||
int from;
|
||||
int to;
|
||||
LongComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(long[] array, long[] supp, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(long[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(long[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1473,8 +1942,7 @@ public class LongArrays
|
||||
int to;
|
||||
LongComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(long[] array, int from, int to, LongComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(long[] array, int from, int to, LongComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1482,8 +1950,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2BooleanLinkedOpenHashMap<T> extends Object2BooleanOpenHashMa
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2BooleanLinkedOpenHashMap<T> extends Object2BooleanOpenHashMa
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2ByteLinkedOpenHashMap<T> extends Object2ByteOpenHashMap<T> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2ByteLinkedOpenHashMap<T> extends Object2ByteOpenHashMap<T> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2CharLinkedOpenHashMap<T> extends Object2CharOpenHashMap<T> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2CharLinkedOpenHashMap<T> extends Object2CharOpenHashMap<T> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2DoubleLinkedOpenHashMap<T> extends Object2DoubleOpenHashMap<
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2DoubleLinkedOpenHashMap<T> extends Object2DoubleOpenHashMap<
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2FloatLinkedOpenHashMap<T> extends Object2FloatOpenHashMap<T>
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2FloatLinkedOpenHashMap<T> extends Object2FloatOpenHashMap<T>
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2IntLinkedOpenHashMap<T> extends Object2IntOpenHashMap<T> imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2IntLinkedOpenHashMap<T> extends Object2IntOpenHashMap<T> imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2LongLinkedOpenHashMap<T> extends Object2LongOpenHashMap<T> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2LongLinkedOpenHashMap<T> extends Object2LongOpenHashMap<T> i
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -208,7 +208,7 @@ public class Object2ObjectLinkedOpenHashMap<T, V> extends Object2ObjectOpenHashM
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -232,7 +232,7 @@ public class Object2ObjectLinkedOpenHashMap<T, V> extends Object2ObjectOpenHashM
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -239,7 +239,7 @@ public class Object2ShortLinkedOpenHashMap<T> extends Object2ShortOpenHashMap<T>
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -263,7 +263,7 @@ public class Object2ShortLinkedOpenHashMap<T> extends Object2ShortOpenHashMap<T>
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Objects.hashCode(key)) & mask;
|
||||
while(key == null) {
|
||||
while(keys[pos] != null) {
|
||||
if(Objects.equals(keys[pos], key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+1350
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
+1241
File diff suppressed because it is too large
Load Diff
+1433
File diff suppressed because it is too large
Load Diff
+1372
File diff suppressed because it is too large
Load Diff
+1474
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ import java.util.function.IntFunction;
|
||||
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@@ -252,6 +253,69 @@ public class ObjectArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @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
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
T t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@@ -490,6 +554,55 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectInsertionSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectInsertionSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectInsertionSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
T current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
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
|
||||
@@ -576,6 +689,60 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectSelectionSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectSelectionSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectSelectionSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
T 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;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
T 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
|
||||
@@ -675,6 +842,72 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectMergeSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectMergeSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectMergeSort(T[] array, T[] supp, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -771,6 +1004,56 @@ public class ObjectArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectParallelMergeSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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 swapper the callback which elements were swapped
|
||||
* @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
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectParallelMergeSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectParallelMergeSort(T[] array, T[] supp, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap<>(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@@ -1124,6 +1407,73 @@ public class ObjectArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectQuickSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectQuickSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectQuickSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
T 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1228,6 +1578,58 @@ public class ObjectArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static <T> void indirectParallelQuickSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static <T> void indirectParallelQuickSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> 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
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static <T> void indirectParallelQuickSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap<>(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@@ -1282,6 +1684,18 @@ public class ObjectArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static <T> void swap(T[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
T t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static <T> void swap(T[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static <T> int subMedium(T[] data, int a, int b, int c, int length, Comparator<T> comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@@ -1304,16 +1718,14 @@ public class ObjectArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(T[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(T[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1346,8 +1758,7 @@ public class ObjectArrays
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
|
||||
QuickSortActionComp(T[] array, int from, int to, Comparator<T> comp)
|
||||
{
|
||||
QuickSortActionComp(T[] array, int from, int to, Comparator<T> comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1355,8 +1766,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@@ -1382,6 +1792,49 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
int from;
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
T 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--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap<>(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap<>(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap<>(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap<>(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
@@ -1389,8 +1842,7 @@ public class ObjectArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(T[] array, T[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(T[] array, T[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1398,8 +1850,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1427,8 +1878,7 @@ public class ObjectArrays
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
|
||||
MergeSortActionComp(T[] array, T[] supp, int from, int to, Comparator<T> comp)
|
||||
{
|
||||
MergeSortActionComp(T[] array, T[] supp, int from, int to, Comparator<T> comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@@ -1437,8 +1887,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@@ -1458,22 +1907,64 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
T[] supp;
|
||||
int from;
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(T[] array, T[] supp, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap<>(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap<>(supp, array, mid, to, comp, swapper));
|
||||
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) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(T[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(T[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@@ -1519,8 +2010,7 @@ public class ObjectArrays
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
|
||||
MemFreeMergeSortActionComp(T[] array, int from, int to, Comparator<T> comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(T[] array, int from, int to, Comparator<T> comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@@ -1528,8 +2018,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Short2BooleanLinkedOpenHashMap extends Short2BooleanOpenHashMap imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Short.hashCode(key)) & mask;
|
||||
while(key == (short)0) {
|
||||
while(keys[pos] != (short)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Short2BooleanLinkedOpenHashMap extends Short2BooleanOpenHashMap imp
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Short.hashCode(key)) & mask;
|
||||
while(key == (short)0) {
|
||||
while(keys[pos] != (short)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Short2ByteLinkedOpenHashMap extends Short2ByteOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Short.hashCode(key)) & mask;
|
||||
while(key == (short)0) {
|
||||
while(keys[pos] != (short)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Short2ByteLinkedOpenHashMap extends Short2ByteOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Short.hashCode(key)) & mask;
|
||||
while(key == (short)0) {
|
||||
while(keys[pos] != (short)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
+2
-2
@@ -249,7 +249,7 @@ public class Short2CharLinkedOpenHashMap extends Short2CharOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Short.hashCode(key)) & mask;
|
||||
while(key == (short)0) {
|
||||
while(keys[pos] != (short)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ public class Short2CharLinkedOpenHashMap extends Short2CharOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Short.hashCode(key)) & mask;
|
||||
while(key == (short)0) {
|
||||
while(keys[pos] != (short)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user