Sync with latest changes
This commit is contained in:
parent
4db9c69a54
commit
e56e136459
@ -48,7 +48,7 @@ dependencies {
|
||||
builderImplementation 'com.google.code.gson:gson:2.10'
|
||||
builderImplementation 'de.speiger:Simple-Code-Generator:1.3.0'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
testImplementation 'com.google.guava:guava-testlib:31.0.1-jre'
|
||||
testImplementation 'com.google.guava:guava-testlib:33.6.0-jre'
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -36,6 +36,10 @@ public class MapModule extends BaseModule
|
||||
public static final FunctionDependency ENUM_MAP = MODULE.createDependency("EnumMap").addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency LINKED_ENUM_MAP = MODULE.createDependency("LinkedEnumMap").addEntryDependency(ENUM_MAP).addEntryDependency(ORDERED_MAP);
|
||||
|
||||
public static final FunctionDependency REF_MAP = MODULE.createDependency("ReferenceHashMap").addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency LINKED_REF_MAP = MODULE.createDependency("LinkedReferenceMap").addEntryDependency(REF_MAP).addEntryDependency(ORDERED_MAP);
|
||||
|
||||
|
||||
public static final FunctionDependency CONCURRENT_MAP = MODULE.createDependency("ConcurrentMap").addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency AVL_TREE_MAP = MODULE.createDependency("AVLTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
|
||||
public static final FunctionDependency RB_TREE_MAP = MODULE.createDependency("RBTreeMap").addEntryDependency(SORTED_MAP).addEntryDependency(IMPLEMENTATION);
|
||||
@ -51,7 +55,7 @@ public class MapModule extends BaseModule
|
||||
@Override
|
||||
public List<IDependency> getDependencies(ClassType keyType, ClassType valueType) {
|
||||
List<IDependency> dependencies = new ArrayList<>(Arrays.asList(MODULE, ORDERED_MAP, SORTED_MAP, IMPLEMENTATION, WRAPPERS, ARRAY_MAP, IMMUTABLE_MAP, HASH_MAP, LINKED_MAP, CUSTOM_MAP, LINKED_CUSTOM_MAP, CONCURRENT_MAP, AVL_TREE_MAP, RB_TREE_MAP));
|
||||
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP));
|
||||
if(keyType == ClassType.OBJECT) dependencies.addAll(Arrays.asList(ENUM_MAP, LINKED_ENUM_MAP, REF_MAP, LINKED_REF_MAP));
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@ -70,6 +74,10 @@ public class MapModule extends BaseModule
|
||||
if(AVL_TREE_MAP.isEnabled()) addFlag("AVL_TREE_MAP_FEATURE");
|
||||
if(RB_TREE_MAP.isEnabled()) addFlag("RB_TREE_MAP_FEATURE");
|
||||
|
||||
if(REF_MAP.isEnabled()) addFlag("REF_MAP_FEATURE");
|
||||
if(LINKED_REF_MAP.isEnabled()) addFlag("LINKED_REF_MAP_FEATURE");
|
||||
|
||||
|
||||
if(CONCURRENT_MAP.isEnabled()) addFlag("CONCURRENT_MAP_FEATURE");
|
||||
if(IMMUTABLE_MAP.isEnabled()) addFlag("IMMUTABLE_MAP_FEATURE");
|
||||
if(HASH_MAP.isEnabled()) addFlag("MAP_FEATURE");
|
||||
@ -85,6 +93,8 @@ public class MapModule extends BaseModule
|
||||
if(!IMMUTABLE_MAP.isEnabled()) addBlockedFiles("ImmutableOpenHashMap");
|
||||
if(!CONCURRENT_MAP.isEnabled()) addBlockedFiles("ConcurrentMap", "ConcurrentOpenHashMap");
|
||||
if(!ORDERED_MAP.isEnabled()) addBlockedFiles("OrderedMap");
|
||||
if(!REF_MAP.isEnabled()) addBlockedFiles("ReferenceHashMap");
|
||||
if(!LINKED_REF_MAP.isEnabled()) addBlockedFiles("LinkedReferenceHashMap");
|
||||
if(!HASH_MAP.isEnabled()) addBlockedFiles("OpenHashMap");
|
||||
if(!LINKED_MAP.isEnabled()) addBlockedFiles("LinkedOpenHashMap");
|
||||
if(!CUSTOM_MAP.isEnabled()) addBlockedFiles("OpenCustomHashMap");
|
||||
@ -127,6 +137,8 @@ public class MapModule extends BaseModule
|
||||
addBiRequirement("AbstractMap");
|
||||
addEnumRequirement("EnumMap");
|
||||
addEnumRequirement("LinkedEnumMap");
|
||||
addEnumRequirement("ReferenceHashMap");
|
||||
addEnumRequirement("LinkedReferenceHashMap");
|
||||
addBiRequirement("ConcurrentOpenHashMap");
|
||||
addBiRequirement("ImmutableOpenHashMap");
|
||||
addBiRequirement("OpenHashMap");
|
||||
@ -141,6 +153,8 @@ public class MapModule extends BaseModule
|
||||
addRemapper("AbstractMap", "Abstract%sMap");
|
||||
addRemapper("EnumMap", "Enum2%sMap");
|
||||
addRemapper("LinkedEnumMap", "LinkedEnum2%sMap");
|
||||
addRemapper("ReferenceHashMap", "Reference2%sHashMap");
|
||||
addRemapper("LinkedReferenceHashMap", "Reference2%sLinkedHashMap");
|
||||
addRemapper("ImmutableOpenHashMap", "Immutable%sOpenHashMap");
|
||||
|
||||
//Test Classes
|
||||
@ -249,6 +263,8 @@ public class MapModule extends BaseModule
|
||||
addBiClassMapper("RB_TREE_MAP", "RBTreeMap", "2");
|
||||
addFunctionValueMappers("LINKED_ENUM_MAP", valueType.isObject() ? "LinkedEnum2ObjectMap" : "LinkedEnum2%sMap");
|
||||
addFunctionValueMappers("ENUM_MAP", valueType.isObject() ? "Enum2ObjectMap" : "Enum2%sMap");
|
||||
addFunctionValueMappers("REF_MAP", valueType.isObject() ? "Reference2ObjectHashMap" : "Reference2%sHashMap");
|
||||
addFunctionValueMappers("LINKED_REF_MAP", valueType.isObject() ? "Reference2ObjectLinkedHashMap" : "Reference2%sLinkedHashMap");
|
||||
addBiClassMapper("HASH_MAP", "OpenHashMap", "2");
|
||||
addBiClassMapper("ARRAY_MAP", "ArrayMap", "2");
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,7 @@ import java.util.function.IntFunction;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.collections.ITERATOR;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -337,6 +338,69 @@ public class ARRAYS
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, RANDOM random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, int length, RANDOM random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @ArrayType(T)
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectShuffle(KEY_TYPE[] array, int offset, int length, RANDOM random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
KEY_TYPE t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -575,6 +639,55 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectInsertionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectInsertionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectInsertionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
KEY_TYPE current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -661,6 +774,60 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectSelectionSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectSelectionSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectSelectionSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
KEY_TYPE min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
KEY_TYPE temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -760,6 +927,72 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -856,6 +1089,56 @@ public class ARRAYS
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectParallelMergeSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectParallelMergeSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectParallelMergeSort(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwapBRACES(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1209,6 +1492,73 @@ public class ARRAYS
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @return input array
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES KEY_TYPE[] indirectQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1313,6 +1663,58 @@ public class ARRAYS
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectParallelQuickSort(KEY_TYPE[] array, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectParallelQuickSort(KEY_TYPE[] array, int length, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @ArrayType(T)
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static GENERIC_KEY_BRACES void indirectParallelQuickSort(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwapBRACES(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1367,6 +1769,18 @@ public class ARRAYS
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
KEY_TYPE t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static GENERIC_KEY_BRACES void swap(KEY_TYPE[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static GENERIC_KEY_BRACES int subMedium(KEY_TYPE[] data, int a, int b, int c, int length, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1389,16 +1803,14 @@ public class ARRAYS
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(KEY_TYPE[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(KEY_TYPE[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1431,8 +1843,7 @@ public class ARRAYS
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
|
||||
QuickSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||||
{
|
||||
QuickSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1440,8 +1851,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1467,6 +1877,49 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap KEY_GENERIC_TYPE extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
KEY_TYPE[] array;
|
||||
int from;
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
KEY_TYPE pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwapBRACES(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwapBRACES(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwapBRACES(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwapBRACES(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
KEY_TYPE[] array;
|
||||
@ -1474,8 +1927,7 @@ public class ARRAYS
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1483,8 +1935,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1512,8 +1963,7 @@ public class ARRAYS
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
|
||||
MergeSortActionComp(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||||
{
|
||||
MergeSortActionComp(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1522,8 +1972,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1543,22 +1992,64 @@ public class ARRAYS
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap KEY_GENERIC_TYPE extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
KEY_TYPE[] array;
|
||||
KEY_TYPE[] supp;
|
||||
int from;
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(KEY_TYPE[] array, KEY_TYPE[] supp, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwapBRACES(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwapBRACES(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction KEY_GENERIC_TYPE extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
KEY_TYPE[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(KEY_TYPE[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1604,8 +2095,7 @@ public class ARRAYS
|
||||
int to;
|
||||
COMPARATOR KEY_GENERIC_TYPE comp;
|
||||
|
||||
MemFreeMergeSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(KEY_TYPE[] array, int from, int to, COMPARATOR KEY_GENERIC_TYPE comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1613,8 +2103,7 @@ public class ARRAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -27,6 +27,8 @@ import speiger.src.collections.PACKAGE.maps.impl.concurrent.CONCURRENT_HASH_MAP;
|
||||
#if TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.REF_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.LINKED_REF_MAP;
|
||||
#endif
|
||||
|
||||
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
|
||||
@ -134,6 +136,97 @@ public class MAP_CONSTRUCTOR_TESTS
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
public static class RefMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester KEY_VALUE_STRING_GENERIC_TYPE
|
||||
{
|
||||
public RefMap() {
|
||||
setSimpleConstructor(REF_MAP::new);
|
||||
setSizeConstructor(REF_MAP::new);
|
||||
setPArrayConstructor(REF_MAP::new);
|
||||
#if !TYPE_OBJECT || !VALUE_OBJECT
|
||||
setArrayConstructor(REF_MAP::new);
|
||||
#endif
|
||||
setPMapConstructor(REF_MAP::new);
|
||||
setMapConstructor(REF_MAP::new);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongLoadFactorSize() {
|
||||
setSizeConstructor(T -> new REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 0F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 0 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {}
|
||||
|
||||
setSizeConstructor(T -> new REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 1F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 1 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {}
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@Override
|
||||
protected String[] createKeyElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 0, 100);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
@Override
|
||||
protected String[] createValueElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 100, 200);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
public static class LinkedRefMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester KEY_VALUE_STRING_GENERIC_TYPE
|
||||
{
|
||||
public LinkedRefMap() {
|
||||
setSimpleConstructor(LINKED_REF_MAP::new);
|
||||
setSizeConstructor(LINKED_REF_MAP::new);
|
||||
setPArrayConstructor(LINKED_REF_MAP::new);
|
||||
#if !TYPE_OBJECT || !VALUE_OBJECT
|
||||
setArrayConstructor(LINKED_REF_MAP::new);
|
||||
#endif
|
||||
setPMapConstructor(LINKED_REF_MAP::new);
|
||||
setMapConstructor(LINKED_REF_MAP::new);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongLoadFactorSize() {
|
||||
setSizeConstructor(T -> new LINKED_REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 0F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 0 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {
|
||||
}
|
||||
|
||||
setSizeConstructor(T -> new LINKED_REF_MAP KEY_VALUE_STRING_GENERIC_TYPE(T, 1F));
|
||||
try {
|
||||
testSizeConstructor_smallSize();
|
||||
fail("A Constructor using a 1 LoadFactor should error");
|
||||
} catch(IllegalStateException e) {
|
||||
}
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@Override
|
||||
protected String[] createKeyElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 0, 100);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
@Override
|
||||
protected String[] createValueElements() {
|
||||
return Arrays.copyOfRange(StringSortTest.NAMES, 100, 200);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if VALUE_OBJECT
|
||||
public static class EnumMap extends FILE_KEY_TYPE2FILE_VALUE_TYPEMapConstructorTester<AnEnum, String>
|
||||
#else
|
||||
|
||||
@ -41,6 +41,8 @@ import speiger.src.collections.PACKAGE.maps.impl.misc.ARRAY_MAP;
|
||||
#if TYPE_OBJECT
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.misc.LINKED_ENUM_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.REF_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.reference.LINKED_REF_MAP;
|
||||
#endif
|
||||
import speiger.src.collections.PACKAGE.maps.impl.tree.AVL_TREE_MAP;
|
||||
import speiger.src.collections.PACKAGE.maps.impl.tree.RB_TREE_MAP;
|
||||
@ -104,6 +106,7 @@ public class MAP_TESTS extends TestCase
|
||||
#if TYPE_OBJECT
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.EnumMap.class));
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.LinkedEnumMap.class));
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.RefMap.class));
|
||||
#endif
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.CustomHashMap.class));
|
||||
constructors.addTest(new TestSuite(MAP_CONSTRUCTOR_TESTS.LinkedCustomHashMap.class));
|
||||
@ -130,27 +133,29 @@ public class MAP_TESTS extends TestCase
|
||||
}
|
||||
|
||||
public static void suite(TestSuite suite) {
|
||||
suite.addTest(mapSuite("HASH_MAP", HASH_MAP::new, getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_HASH_MAP", LINKED_HASH_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("IMMUTABLE_HASH_MAP", IMMUTABLE_HASH_MAP::new, getImmutableFeatures(), -1));
|
||||
suite.addTest(mapSuite("HASH_MAP", HASH_MAP::new, getFeatures(), -1, true, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_HASH_MAP", LINKED_HASH_MAP::new, getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("IMMUTABLE_HASH_MAP", IMMUTABLE_HASH_MAP::new, getImmutableFeatures(), -1, true));
|
||||
#if TYPE_OBJECT
|
||||
suite.addTest(enumMapSuite("ENUM_MAP", ENUM_MAP::new, getFeatures(), 5));
|
||||
suite.addTest(enumOrderedMapSuite("LINKED_ENUM_MAP", (K, V) -> K.length <= 0 ? new LINKED_ENUM_MAP<>(AnEnum.class) : new LINKED_ENUM_MAP<>(K, V), getFeatures(), 5));
|
||||
suite.addTest(mapSuite("REF_MAP", REF_MAP::new, getFeatures(), - 1, true, false));
|
||||
suite.addTest(orderedMapSuite("LINKED_REF_MAP", LINKED_REF_MAP::new, getFeatures(), - 1, false));
|
||||
#endif
|
||||
suite.addTest(mapSuite("CUSTOM_HASH_MAP", (K, V) -> new CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_CUSTOM_HASH_MAP", (K, V) -> new LINKED_CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("ARRAY_MAP", ARRAY_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(mapSuite("CUSTOM_HASH_MAP", (K, V) -> new CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true, true));
|
||||
suite.addTest(orderedMapSuite("LINKED_CUSTOM_HASH_MAP", (K, V) -> new LINKED_CUSTOM_HASH_MAPKV_BRACES(K, V, HashStrategy.INSTANCE), getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("ARRAY_MAP", ARRAY_MAP::new, getFeatures(), -1, true));
|
||||
suite.addTest(concurrentMapSuite("CONCURRENT_HASH_MAP", CONCURRENT_HASH_MAP::new, getFeatures(), 2));
|
||||
suite.addTest(concurrentMapSuite("CONCURRENT_HASH_MAP", CONCURRENT_HASH_MAP::new, getFeatures(), 3));
|
||||
suite.addTest(navigableMapSuite("RB_TREE_MAP", RB_TREE_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(navigableMapSuite("AVL_TREE_MAP", AVL_TREE_MAP::new, getFeatures(), -1));
|
||||
suite.addTest(navigableMapSuite("SynchronizedRB_TREE_MAP", (K, V) -> new RB_TREE_MAPKV_BRACES(K, V).synchronize(), getLimitedFeatures(), -1));
|
||||
suite.addTest(navigableMapSuite("UnmodifiableRB_TREE_MAP", (K, V) -> new RB_TREE_MAPKV_BRACES(K, V).unmodifiable(), getLimitedImmutableFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("SynchronizedORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).synchronize(), getFeatures(), -1));
|
||||
suite.addTest(orderedMapSuite("UnmodifiableORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).unmodifiable(), getImmutableFeatures(), -1));
|
||||
suite.addTest(mapSuite("EmptyMAP", (K, V) -> MAPS.empty(), getEmptyFeatures(), 0, false));
|
||||
suite.addTest(mapSuite("SingletonMAP", (K, V) -> MAPS.singleton(K[0], V[0]), getEmptyFeatures(), 1, false));
|
||||
suite.addTest(mapSuite("AbstractMap", SIMPLE_TEST_MAP::new, getTestFeatures(), -1, false));
|
||||
suite.addTest(orderedMapSuite("SynchronizedORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).synchronize(), getFeatures(), -1, true));
|
||||
suite.addTest(orderedMapSuite("UnmodifiableORDERED_MAP", (K, V) -> new LINKED_HASH_MAPKV_BRACES(K, V).unmodifiable(), getImmutableFeatures(), -1, true));
|
||||
suite.addTest(mapSuite("EmptyMAP", (K, V) -> MAPS.empty(), getEmptyFeatures(), 0, false, true));
|
||||
suite.addTest(mapSuite("SingletonMAP", (K, V) -> MAPS.singleton(K[0], V[0]), getEmptyFeatures(), 1, false, true));
|
||||
suite.addTest(mapSuite("AbstractMap", SIMPLE_TEST_MAP::new, getTestFeatures(), -1, false, true));
|
||||
}
|
||||
|
||||
#if TYPE_OBJECT
|
||||
@ -209,14 +214,14 @@ public class MAP_TESTS extends TestCase
|
||||
|
||||
#endif
|
||||
|
||||
private static Test mapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean sorted) {
|
||||
private static Test mapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean sorted, boolean allowNullKeys) {
|
||||
SIMPLE_MAP_TEST_GENERATOR.Maps KEY_VALUE_STRING_GENERIC_TYPE generator = new SIMPLE_MAP_TEST_GENERATOR.Maps KEY_VALUE_STRING_GENERIC_TYPE(factory);
|
||||
MAP_TEST_BUILDER KEY_VALUE_STRING_GENERIC_TYPE builder = MAP_TEST_BUILDER.using(generator);
|
||||
builder.shouldBlockKeys(sorted);
|
||||
#if TYPE_OBJECT
|
||||
generator.setKeys(createKeys());
|
||||
#ignore
|
||||
builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
if(allowNullKeys) builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
#endignore
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
@ -265,13 +270,13 @@ public class MAP_TESTS extends TestCase
|
||||
return builder.named(name).createTestSuite();
|
||||
}
|
||||
|
||||
private static Test orderedMapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], ORDERED_MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size) {
|
||||
private static Test orderedMapSuite(String name, BiFunction<KEY_STRING_TYPE[], VALUE_STRING_TYPE[], ORDERED_MAP KEY_VALUE_STRING_GENERIC_TYPE> factory, Collection<Feature<?>> features, int size, boolean allowNullKeys) {
|
||||
SIMPLE_MAP_TEST_GENERATOR.OrderedMaps KEY_VALUE_STRING_GENERIC_TYPE generator = new SIMPLE_MAP_TEST_GENERATOR.OrderedMaps KEY_VALUE_STRING_GENERIC_TYPE(factory);
|
||||
ORDERED_MAP_TEST_BUILDER KEY_VALUE_STRING_GENERIC_TYPE builder = ORDERED_MAP_TEST_BUILDER.using(generator);
|
||||
#if TYPE_OBJECT
|
||||
generator.setKeys(createKeys());
|
||||
#ignore
|
||||
builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
if(allowNullKeys) builder.withFeatures(MapFeature.ALLOWS_NULL_KEYS);
|
||||
#endignore
|
||||
#endif
|
||||
#if VALUE_OBJECT
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.booleans.functions.BooleanComparator;
|
||||
import speiger.src.collections.booleans.collections.BooleanIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class BooleanArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static boolean[] indirectShuffle(boolean[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
boolean t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectInsertionSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
boolean current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectSelectionSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
boolean min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
boolean temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectMergeSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class BooleanArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class BooleanArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static boolean[] indirectQuickSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
boolean pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class BooleanArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(boolean[] array, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(boolean[] array, int length, BooleanComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class BooleanArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(boolean[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
boolean t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(boolean[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(boolean[] data, int a, int b, int c, int length, BooleanComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class BooleanArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(boolean[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(boolean[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class BooleanArrays
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
|
||||
QuickSortActionComp(boolean[] array, int from, int to, BooleanComparator comp)
|
||||
{
|
||||
QuickSortActionComp(boolean[] array, int from, int to, BooleanComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
int from;
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(boolean[] array, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
boolean pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
@ -1343,8 +1774,7 @@ public class BooleanArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(boolean[] array, boolean[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(boolean[] array, boolean[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class BooleanArrays
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
|
||||
MergeSortActionComp(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp)
|
||||
{
|
||||
MergeSortActionComp(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class BooleanArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
boolean[] supp;
|
||||
int from;
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(boolean[] array, boolean[] supp, int from, int to, BooleanComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
boolean[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(boolean[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(boolean[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class BooleanArrays
|
||||
int to;
|
||||
BooleanComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(boolean[] array, int from, int to, BooleanComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(boolean[] array, int from, int to, BooleanComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class BooleanArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ public class Byte2ShortLinkedOpenHashMap extends Byte2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@ -273,7 +273,7 @@ public class Byte2ShortLinkedOpenHashMap extends Byte2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Byte.hashCode(key)) & mask;
|
||||
while(key == (byte)0) {
|
||||
while(keys[pos] != (byte)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.bytes.functions.ByteComparator;
|
||||
import speiger.src.collections.bytes.collections.ByteIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class ByteArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static byte[] indirectShuffle(byte[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
byte t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectInsertionSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
byte current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectSelectionSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
byte min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
byte temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectMergeSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(byte[] array, byte[] supp, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class ByteArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(byte[] array, byte[] supp, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class ByteArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static byte[] indirectQuickSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
byte pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class ByteArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(byte[] array, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(byte[] array, int length, ByteComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class ByteArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(byte[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
byte t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(byte[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(byte[] data, int a, int b, int c, int length, ByteComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class ByteArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(byte[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(byte[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class ByteArrays
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
|
||||
QuickSortActionComp(byte[] array, int from, int to, ByteComparator comp)
|
||||
{
|
||||
QuickSortActionComp(byte[] array, int from, int to, ByteComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
int from;
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(byte[] array, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
byte pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
@ -1343,8 +1774,7 @@ public class ByteArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(byte[] array, byte[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(byte[] array, byte[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class ByteArrays
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
|
||||
MergeSortActionComp(byte[] array, byte[] supp, int from, int to, ByteComparator comp)
|
||||
{
|
||||
MergeSortActionComp(byte[] array, byte[] supp, int from, int to, ByteComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class ByteArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
byte[] supp;
|
||||
int from;
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(byte[] array, byte[] supp, int from, int to, ByteComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
byte[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(byte[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(byte[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class ByteArrays
|
||||
int to;
|
||||
ByteComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(byte[] array, int from, int to, ByteComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(byte[] array, int from, int to, ByteComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class ByteArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ public class Char2ShortLinkedOpenHashMap extends Char2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@ -273,7 +273,7 @@ public class Char2ShortLinkedOpenHashMap extends Char2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Character.hashCode(key)) & mask;
|
||||
while(key == (char)0) {
|
||||
while(keys[pos] != (char)0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.chars.functions.CharComparator;
|
||||
import speiger.src.collections.chars.collections.CharIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class CharArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static char[] indirectShuffle(char[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
char t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectInsertionSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
char current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectSelectionSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
char min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
char temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectMergeSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(char[] array, char[] supp, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class CharArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(char[] array, char[] supp, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class CharArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static char[] indirectQuickSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
char pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class CharArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(char[] array, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(char[] array, int length, CharComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class CharArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(char[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
char t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(char[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(char[] data, int a, int b, int c, int length, CharComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class CharArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(char[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(char[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class CharArrays
|
||||
int to;
|
||||
CharComparator comp;
|
||||
|
||||
QuickSortActionComp(char[] array, int from, int to, CharComparator comp)
|
||||
{
|
||||
QuickSortActionComp(char[] array, int from, int to, CharComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
int from;
|
||||
int to;
|
||||
CharComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(char[] array, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
char pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
@ -1343,8 +1774,7 @@ public class CharArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(char[] array, char[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(char[] array, char[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class CharArrays
|
||||
int to;
|
||||
CharComparator comp;
|
||||
|
||||
MergeSortActionComp(char[] array, char[] supp, int from, int to, CharComparator comp)
|
||||
{
|
||||
MergeSortActionComp(char[] array, char[] supp, int from, int to, CharComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class CharArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
char[] supp;
|
||||
int from;
|
||||
int to;
|
||||
CharComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(char[] array, char[] supp, int from, int to, CharComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
char[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(char[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(char[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class CharArrays
|
||||
int to;
|
||||
CharComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(char[] array, int from, int to, CharComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(char[] array, int from, int to, CharComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class CharArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ public class Double2ShortLinkedOpenHashMap extends Double2ShortOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@ -273,7 +273,7 @@ public class Double2ShortLinkedOpenHashMap extends Double2ShortOpenHashMap imple
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Double.hashCode(key)) & mask;
|
||||
while(Double.doubleToLongBits(key) == 0) {
|
||||
while(Double.doubleToLongBits(keys[pos]) != 0) {
|
||||
if(Double.doubleToLongBits(keys[pos]) == Double.doubleToLongBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.doubles.functions.DoubleComparator;
|
||||
import speiger.src.collections.doubles.collections.DoubleIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class DoubleArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static double[] indirectShuffle(double[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
double t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectInsertionSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
double current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectSelectionSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
double min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
double temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectMergeSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(double[] array, double[] supp, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class DoubleArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(double[] array, double[] supp, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class DoubleArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static double[] indirectQuickSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
double pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class DoubleArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(double[] array, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(double[] array, int length, DoubleComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class DoubleArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(double[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
double t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(double[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(double[] data, int a, int b, int c, int length, DoubleComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class DoubleArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(double[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(double[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class DoubleArrays
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
|
||||
QuickSortActionComp(double[] array, int from, int to, DoubleComparator comp)
|
||||
{
|
||||
QuickSortActionComp(double[] array, int from, int to, DoubleComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
int from;
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(double[] array, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
double pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
@ -1343,8 +1774,7 @@ public class DoubleArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(double[] array, double[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(double[] array, double[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class DoubleArrays
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
|
||||
MergeSortActionComp(double[] array, double[] supp, int from, int to, DoubleComparator comp)
|
||||
{
|
||||
MergeSortActionComp(double[] array, double[] supp, int from, int to, DoubleComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class DoubleArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
double[] supp;
|
||||
int from;
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(double[] array, double[] supp, int from, int to, DoubleComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
double[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(double[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(double[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class DoubleArrays
|
||||
int to;
|
||||
DoubleComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(double[] array, int from, int to, DoubleComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(double[] array, int from, int to, DoubleComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class DoubleArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ public class Float2ShortLinkedOpenHashMap extends Float2ShortOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@ -273,7 +273,7 @@ public class Float2ShortLinkedOpenHashMap extends Float2ShortOpenHashMap impleme
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Float.hashCode(key)) & mask;
|
||||
while(Float.floatToIntBits(key) == 0) {
|
||||
while(Float.floatToIntBits(keys[pos]) != 0) {
|
||||
if(Float.floatToIntBits(keys[pos]) == Float.floatToIntBits(key)) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.floats.functions.FloatComparator;
|
||||
import speiger.src.collections.floats.collections.FloatIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class FloatArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static float[] indirectShuffle(float[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
float t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectInsertionSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
float current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectSelectionSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
float min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
float temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectMergeSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(float[] array, float[] supp, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class FloatArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(float[] array, float[] supp, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class FloatArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static float[] indirectQuickSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
float pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class FloatArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(float[] array, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(float[] array, int length, FloatComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class FloatArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(float[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
float t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(float[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(float[] data, int a, int b, int c, int length, FloatComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class FloatArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(float[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(float[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class FloatArrays
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
|
||||
QuickSortActionComp(float[] array, int from, int to, FloatComparator comp)
|
||||
{
|
||||
QuickSortActionComp(float[] array, int from, int to, FloatComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
int from;
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(float[] array, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
float pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
@ -1343,8 +1774,7 @@ public class FloatArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(float[] array, float[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(float[] array, float[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class FloatArrays
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
|
||||
MergeSortActionComp(float[] array, float[] supp, int from, int to, FloatComparator comp)
|
||||
{
|
||||
MergeSortActionComp(float[] array, float[] supp, int from, int to, FloatComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class FloatArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
float[] supp;
|
||||
int from;
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(float[] array, float[] supp, int from, int to, FloatComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
float[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(float[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(float[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class FloatArrays
|
||||
int to;
|
||||
FloatComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(float[] array, int from, int to, FloatComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(float[] array, int from, int to, FloatComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class FloatArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ public class Int2ShortLinkedOpenHashMap extends Int2ShortOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@ -272,7 +272,7 @@ public class Int2ShortLinkedOpenHashMap extends Int2ShortOpenHashMap implements
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Integer.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.ints.functions.IntComparator;
|
||||
import speiger.src.collections.ints.collections.IntIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class IntArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static int[] indirectShuffle(int[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
int t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectInsertionSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
int current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectSelectionSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
int min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
int temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectMergeSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(int[] array, int[] supp, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class IntArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(int[] array, int[] supp, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class IntArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static int[] indirectQuickSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
int pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class IntArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(int[] array, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(int[] array, int length, IntComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class IntArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(int[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
int t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(int[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(int[] data, int a, int b, int c, int length, IntComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class IntArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(int[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(int[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class IntArrays
|
||||
int to;
|
||||
IntComparator comp;
|
||||
|
||||
QuickSortActionComp(int[] array, int from, int to, IntComparator comp)
|
||||
{
|
||||
QuickSortActionComp(int[] array, int from, int to, IntComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
int from;
|
||||
int to;
|
||||
IntComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(int[] array, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
int pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
@ -1343,8 +1774,7 @@ public class IntArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(int[] array, int[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(int[] array, int[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class IntArrays
|
||||
int to;
|
||||
IntComparator comp;
|
||||
|
||||
MergeSortActionComp(int[] array, int[] supp, int from, int to, IntComparator comp)
|
||||
{
|
||||
MergeSortActionComp(int[] array, int[] supp, int from, int to, IntComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class IntArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
int[] supp;
|
||||
int from;
|
||||
int to;
|
||||
IntComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(int[] array, int[] supp, int from, int to, IntComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
int[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(int[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(int[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class IntArrays
|
||||
int to;
|
||||
IntComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(int[] array, int from, int to, IntComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(int[] array, int from, int to, IntComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class IntArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ public class Long2ShortLinkedOpenHashMap extends Long2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
@ -273,7 +273,7 @@ public class Long2ShortLinkedOpenHashMap extends Long2ShortOpenHashMap implement
|
||||
}
|
||||
else {
|
||||
int pos = HashUtil.mix(Long.hashCode(key)) & mask;
|
||||
while(key == 0) {
|
||||
while(keys[pos] != 0) {
|
||||
if(keys[pos] == key) return values[pos];
|
||||
pos = ++pos & mask;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.RecursiveAction;
|
||||
import speiger.src.collections.longs.functions.LongComparator;
|
||||
import speiger.src.collections.longs.collections.LongIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -269,6 +270,65 @@ public class LongArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static long[] indirectShuffle(long[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
long t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -489,6 +549,52 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectInsertionSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectInsertionSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
long current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -569,6 +675,57 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectSelectionSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectSelectionSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
long min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
long temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -662,6 +819,69 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectMergeSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectMergeSort(long[] array, long[] supp, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -752,6 +972,53 @@ public class LongArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelMergeSort(long[] array, long[] supp, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1087,6 +1354,70 @@ public class LongArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @return input array
|
||||
*/
|
||||
public static long[] indirectQuickSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
*/
|
||||
public static void indirectQuickSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
long pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1185,6 +1516,55 @@ public class LongArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(long[] array, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(long[] array, int length, LongComparator comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static void indirectParallelQuickSort(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1236,6 +1616,18 @@ public class LongArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static void swap(long[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
long t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static void swap(long[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static int subMedium(long[] data, int a, int b, int c, int length, LongComparator comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1258,16 +1650,14 @@ public class LongArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(long[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(long[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1300,8 +1690,7 @@ public class LongArrays
|
||||
int to;
|
||||
LongComparator comp;
|
||||
|
||||
QuickSortActionComp(long[] array, int from, int to, LongComparator comp)
|
||||
{
|
||||
QuickSortActionComp(long[] array, int from, int to, LongComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1309,8 +1698,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1336,6 +1724,49 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
int from;
|
||||
int to;
|
||||
LongComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(long[] array, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
long pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
@ -1343,8 +1774,7 @@ public class LongArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(long[] array, long[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(long[] array, long[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1352,8 +1782,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1381,8 +1810,7 @@ public class LongArrays
|
||||
int to;
|
||||
LongComparator comp;
|
||||
|
||||
MergeSortActionComp(long[] array, long[] supp, int from, int to, LongComparator comp)
|
||||
{
|
||||
MergeSortActionComp(long[] array, long[] supp, int from, int to, LongComparator comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1391,8 +1819,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1412,22 +1839,64 @@ public class LongArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
long[] supp;
|
||||
int from;
|
||||
int to;
|
||||
LongComparator comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(long[] array, long[] supp, int from, int to, LongComparator comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
long[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(long[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(long[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1473,8 +1942,7 @@ public class LongArrays
|
||||
int to;
|
||||
LongComparator comp;
|
||||
|
||||
MemFreeMergeSortActionComp(long[] array, int from, int to, LongComparator comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(long[] array, int from, int to, LongComparator comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1482,8 +1950,7 @@ public class LongArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,7 @@ import java.util.function.IntFunction;
|
||||
|
||||
import speiger.src.collections.objects.collections.ObjectIterator;
|
||||
import speiger.src.collections.utils.SanityChecks;
|
||||
import speiger.src.collections.utils.Swapper;
|
||||
|
||||
/**
|
||||
* A Helper class for Arrays
|
||||
@ -252,6 +253,69 @@ public class ObjectArrays
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This uses the SanityChecks#getRandom
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, Swapper swapper) {
|
||||
return indirectShuffle(array, SanityChecks.getRandom(), swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, array.length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, int length, Random random, Swapper swapper) {
|
||||
return indirectShuffle(array, 0, length, random, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Shuffle method for Arrays.
|
||||
* With a Callback for indirect shuffling
|
||||
* @param array the elements that should be shuffled
|
||||
* @param offset the start array
|
||||
* @param length the length of the array
|
||||
* @param random the Random Number Generator that should be used for the shuffling
|
||||
* @param swapper the callback on the swaps
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return the provided sorted array
|
||||
*/
|
||||
public static <T> T[] indirectShuffle(T[] array, int offset, int length, Random random, Swapper swapper) {
|
||||
for(int i = length-1; i>=0;i--) {
|
||||
int j = offset + i;
|
||||
int p = offset + random.nextInt(i + 1);
|
||||
swapper.swap(j, p);
|
||||
T t = array[j];
|
||||
array[j] = array[p];
|
||||
array[p] = t;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple Array Reversal method
|
||||
* @param array the Array that should flip
|
||||
@ -490,6 +554,55 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectInsertionSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectInsertionSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectInsertionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Insertion Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectInsertionSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
for (int i = from+1;i<to; i++) {
|
||||
T current = array[i];
|
||||
int j = i - 1;
|
||||
while(j >= from && comp.compare(current, array[j]) < 0) {
|
||||
swapper.swap(j+1, j);
|
||||
array[j+1] = array[j--];
|
||||
}
|
||||
array[j+1] = current;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using InsertionSort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -576,6 +689,60 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectSelectionSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectSelectionSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectSelectionSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Selection Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectSelectionSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
for (int i = from; i < to; i++) {
|
||||
T min = array[i];
|
||||
int minId = i;
|
||||
for(int j = i+1; j < to; j++) {
|
||||
if(comp.compare(array[j], min) < 0) {
|
||||
min = array[j];
|
||||
minId = j;
|
||||
}
|
||||
}
|
||||
swapper.swap(i, minId);
|
||||
T temp = array[i];
|
||||
array[i] = min;
|
||||
array[minId] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Selection Sort,
|
||||
* @param array the array that needs to be sorted
|
||||
@ -675,6 +842,72 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectMergeSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectMergeSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectMergeSort(T[] array, T[] supp, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
indirectMergeSort(supp, array, from, mid, comp, swapper);
|
||||
indirectMergeSort(supp, array, mid, to, comp, swapper);
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -771,6 +1004,56 @@ public class ObjectArrays
|
||||
mergeSort(array, supp, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using a Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectParallelMergeSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectParallelMergeSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelMergeSort(array, null, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Merge Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
* @param array the array that needs to be sorted
|
||||
* @param supp the auxillary array that is used to simplify the sorting
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectParallelMergeSort(T[] array, T[] supp, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new MergeSortActionCompSwap<>(array, supp, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectMergeSort(array, supp, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Merge Sort,
|
||||
* This implementation was copied from <a href="https://github.com/vigna/fastutil">FastUtil</a> with a couple custom optimizations
|
||||
@ -1124,6 +1407,73 @@ public class ObjectArrays
|
||||
if((length = d - c) > 1) quickSort(array, to - length, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @return input array
|
||||
*/
|
||||
public static <T> T[] indirectQuickSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, array.length, comp, swapper);
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectQuickSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
*/
|
||||
public static <T> void indirectQuickSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
T pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if((length = b - a) > 1) indirectQuickSort(array, from, from + length, comp, swapper);
|
||||
if((length = d - c) > 1) indirectQuickSort(array, to - length, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1228,6 +1578,58 @@ public class ObjectArrays
|
||||
quickSort(array, from, to, comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static <T> void indirectParallelQuickSort(T[] array, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, array.length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param length the maxmium size of the array to be sorted
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static <T> void indirectParallelQuickSort(T[] array, int length, Comparator<T> comp, Swapper swapper) {
|
||||
indirectParallelQuickSort(array, 0, length, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the specified range of elements according to the order induced by the specified comparator using Parallel Quick Sort,
|
||||
* On top of that allows to sort other things along with it.
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
* and that sorting Algorithm is based on the tuned quicksort adapted from Jon L. Bentley and M. DouglasMcIlroy, "Engineering a Sort Function", Software: Practice and Experience, 23(11), pages1249−1265, 1993.
|
||||
* @param array the array that needs to be sorted
|
||||
* @param from where the array should be sorted from
|
||||
* @param to where the array should be sorted to
|
||||
* @param comp the Comparator that decides the sorting order
|
||||
* @param swapper the callback which elements were swapped
|
||||
* @param <T> the keyType of array that the operation should be applied
|
||||
* @note This parallelization is invoked through {@link SanityChecks#invokeTask} which the threadpool can be changed as needed
|
||||
*/
|
||||
public static <T> void indirectParallelQuickSort(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
if(SanityChecks.canParallelTask() && to - from >= PARALLEL_THRESHOLD) {
|
||||
SanityChecks.invokeTask(new QuickSortActionCompSwap<>(array, from, to, comp, swapper));
|
||||
return;
|
||||
}
|
||||
indirectQuickSort(array, from, to, comp, swapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array according to the natural ascending order using Parallel Quick Sort,
|
||||
* This implementation is a custom of <a href="https://github.com/vigna/fastutil">FastUtil</a> quicksort but with a different code structure,
|
||||
@ -1282,6 +1684,18 @@ public class ObjectArrays
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++));
|
||||
}
|
||||
|
||||
static <T> void swap(T[] a, int from, int to, Swapper swapper) {
|
||||
swapper.swap(from, to);
|
||||
T t = a[from];
|
||||
a[from] = a[to];
|
||||
a[to] = t;
|
||||
}
|
||||
|
||||
static <T> void swap(T[] a, int from, int to, int length, Swapper swapper) {
|
||||
to -= length;
|
||||
for(int i = 0;i<length;i++,swap(a, from++, to++, swapper));
|
||||
}
|
||||
|
||||
static <T> int subMedium(T[] data, int a, int b, int c, int length, Comparator<T> comp) {
|
||||
return medium(data, medium(data, a, a + length, a + (length * 2), comp), medium(data, b - length, b, b + length, comp), medium(data, c - (length * 2), c - length, c, comp), comp);
|
||||
}
|
||||
@ -1304,16 +1718,14 @@ public class ObjectArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
QuickSortAction(T[] array, int from, int to)
|
||||
{
|
||||
QuickSortAction(T[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1346,8 +1758,7 @@ public class ObjectArrays
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
|
||||
QuickSortActionComp(T[] array, int from, int to, Comparator<T> comp)
|
||||
{
|
||||
QuickSortActionComp(T[] array, int from, int to, Comparator<T> comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1355,8 +1766,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
@ -1382,6 +1792,49 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class QuickSortActionCompSwap<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
int from;
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
Swapper swapper;
|
||||
|
||||
QuickSortActionCompSwap(T[] array, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
int length = to - from;
|
||||
if(length <= 0) return;
|
||||
if(length < BASE_THRESHOLD) {
|
||||
indirectSelectionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
T pivot = array[length > 128 ? subMedium(array, from, from + (length / 2), to - 1, length / 8, comp) : medium(array, from, from + (length / 2), to - 1, comp)];
|
||||
int a = from, b = a, c = to - 1, d = c;
|
||||
for(int compare;;swap(array, b++, c--, swapper)) {
|
||||
for(;b<=c && (compare = comp.compare(array[b], pivot)) <= 0;b++) {
|
||||
if(compare == 0) swap(array, a++, b, swapper);
|
||||
}
|
||||
for(;c>=b && (compare = comp.compare(array[c], pivot)) >= 0;c--) {
|
||||
if(compare == 0) swap(array, c, d--, swapper);
|
||||
}
|
||||
if(b>c) break;
|
||||
}
|
||||
swap(array, from, b, Math.min(a - from, b - a), swapper);
|
||||
swap(array, b, to, Math.min(d - c, to - d - 1), swapper);
|
||||
if(b - a > 1 && d - c > 1) invokeAll(new QuickSortActionCompSwap<>(array, from, from + (b - a), comp, swapper), new QuickSortActionCompSwap<>(array, to - (d - c), to, comp, swapper));
|
||||
else if(b - a > 1) new QuickSortActionCompSwap<>(array, from, from + (b - a), comp, swapper).invoke();
|
||||
else if(d - c > 1) new QuickSortActionCompSwap<>(array, to - (d - c), to, comp, swapper).invoke();
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortAction<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
@ -1389,8 +1842,7 @@ public class ObjectArrays
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MergeSortAction(T[] array, T[] supp, int from, int to)
|
||||
{
|
||||
MergeSortAction(T[] array, T[] supp, int from, int to) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1398,8 +1850,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1427,8 +1878,7 @@ public class ObjectArrays
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
|
||||
MergeSortActionComp(T[] array, T[] supp, int from, int to, Comparator<T> comp)
|
||||
{
|
||||
MergeSortActionComp(T[] array, T[] supp, int from, int to, Comparator<T> comp) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
@ -1437,8 +1887,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
@ -1458,22 +1907,64 @@ public class ObjectArrays
|
||||
}
|
||||
}
|
||||
|
||||
static class MergeSortActionCompSwap<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
T[] supp;
|
||||
int from;
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
Swapper swapper;
|
||||
|
||||
MergeSortActionCompSwap(T[] array, T[] supp, int from, int to, Comparator<T> comp, Swapper swapper) {
|
||||
this.array = array;
|
||||
this.supp = supp;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.comp = comp;
|
||||
this.swapper = swapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
indirectInsertionSort(array, from, to, comp, swapper);
|
||||
return;
|
||||
}
|
||||
if(supp == null) supp = Arrays.copyOf(array, to);
|
||||
int mid = (from + to) >>> 1;
|
||||
invokeAll(new MergeSortActionCompSwap<>(supp, array, from, mid, comp, swapper), new MergeSortActionCompSwap<>(supp, array, mid, to, comp, swapper));
|
||||
if(comp.compare(supp[mid - 1], supp[mid]) <= 0)
|
||||
{
|
||||
System.arraycopy(supp, from, array, from, to - from);
|
||||
return;
|
||||
}
|
||||
for(int p = from, q = mid;from < to;from++) {
|
||||
if(q >= to || p < mid && comp.compare(supp[p], supp[q]) < 0) {
|
||||
swapper.swap(from, p);
|
||||
array[from] = supp[p++];
|
||||
continue;
|
||||
}
|
||||
swapper.swap(from, q);
|
||||
array[from] = supp[q++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class MemFreeMergeSortAction<T> extends RecursiveAction {
|
||||
private static final long serialVersionUID = 0L;
|
||||
T[] array;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
MemFreeMergeSortAction(T[] array, int from, int to)
|
||||
{
|
||||
MemFreeMergeSortAction(T[] array, int from, int to) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to);
|
||||
return;
|
||||
@ -1519,8 +2010,7 @@ public class ObjectArrays
|
||||
int to;
|
||||
Comparator<T> comp;
|
||||
|
||||
MemFreeMergeSortActionComp(T[] array, int from, int to, Comparator<T> comp)
|
||||
{
|
||||
MemFreeMergeSortActionComp(T[] array, int from, int to, Comparator<T> comp) {
|
||||
this.array = array;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
@ -1528,8 +2018,7 @@ public class ObjectArrays
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void compute()
|
||||
{
|
||||
protected void compute() {
|
||||
if(to - from < BASE_THRESHOLD) {
|
||||
insertionSort(array, from, to, comp);
|
||||
return;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user