Sync with latest changes

This commit is contained in:
Speiger 2026-05-14 19:24:20 +02:00
parent 4db9c69a54
commit e56e136459
108 changed files with 33809 additions and 403 deletions

View File

@ -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'
}

View File

@ -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");

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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

View File

@ -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

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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), pages12491265, 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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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