Added version information. Fixed misc 'random.next' typos
This commit is contained in:
parent
8eab208389
commit
9105ca0c6c
|
@ -28,6 +28,8 @@ import java.util.NoSuchElementException;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "SuspiciousSystemArraycopy", "unused", "NullableProblems", "DuplicatedCode"})
|
@SuppressWarnings({"unchecked", "rawtypes", "SuspiciousSystemArraycopy", "unused", "NullableProblems", "DuplicatedCode"})
|
||||||
public class Array<T> implements Iterable<T> {
|
public class Array<T> implements Iterable<T> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
/** Provides direct access to the underlying array. If the Array's generic type is not Object, this field may only be accessed
|
/** Provides direct access to the underlying array. If the Array's generic type is not Object, this field may only be accessed
|
||||||
* if the {@link Array#Array(boolean, int, Class)} constructor was used. */
|
* if the {@link Array#Array(boolean, int, Class)} constructor was used. */
|
||||||
public T[] items;
|
public T[] items;
|
||||||
|
@ -438,7 +440,7 @@ public class Array<T> implements Iterable<T> {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
T[] items = this.items;
|
T[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
T temp = items[i];
|
T temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -477,7 +479,7 @@ public class Array<T> implements Iterable<T> {
|
||||||
/** Returns a random item from the array, or null if the array is empty. */
|
/** Returns a random item from the array, or null if the array is empty. */
|
||||||
public T random () {
|
public T random () {
|
||||||
if (size == 0) return null;
|
if (size == 0) return null;
|
||||||
return items[MathUtil.random(0, size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the items as an array. Note the array is typed, so the {@link #Array(Class)} constructor must have been used.
|
/** Returns the items as an array. Note the array is typed, so the {@link #Array(Class)} constructor must have been used.
|
||||||
|
|
|
@ -31,6 +31,8 @@ import dorkbox.collections.ObjectMap.Entry;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "unused", "SuspiciousSystemArraycopy", "NullableProblems"})
|
@SuppressWarnings({"unchecked", "rawtypes", "unused", "SuspiciousSystemArraycopy", "NullableProblems"})
|
||||||
public class ArrayMap<K, V> implements Iterable<Entry<K, V>> {
|
public class ArrayMap<K, V> implements Iterable<Entry<K, V>> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
public K[] keys;
|
public K[] keys;
|
||||||
public V[] values;
|
public V[] values;
|
||||||
public int size;
|
public int size;
|
||||||
|
@ -384,7 +386,7 @@ public class ArrayMap<K, V> implements Iterable<Entry<K, V>> {
|
||||||
|
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
K tempKey = keys[i];
|
K tempKey = keys[i];
|
||||||
keys[i] = keys[ii];
|
keys[i] = keys[ii];
|
||||||
keys[ii] = tempKey;
|
keys[ii] = tempKey;
|
||||||
|
|
|
@ -43,6 +43,7 @@ import java.util.List;
|
||||||
* @author Tim Boudreau
|
* @author Tim Boudreau
|
||||||
*/
|
*/
|
||||||
public class BinarySearch<T> {
|
public class BinarySearch<T> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private final Evaluator<T> eval;
|
private final Evaluator<T> eval;
|
||||||
private final Indexed<T> indexed;
|
private final Indexed<T> indexed;
|
||||||
|
|
|
@ -26,6 +26,8 @@ import java.util.BitSet;
|
||||||
* removing elements (the last element is moved to the removed element's position).
|
* removing elements (the last element is moved to the removed element's position).
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class BooleanArray {
|
public class BooleanArray {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
public boolean[] items;
|
public boolean[] items;
|
||||||
public int size;
|
public int size;
|
||||||
public boolean ordered;
|
public boolean ordered;
|
||||||
|
@ -281,7 +283,7 @@ public class BooleanArray {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
boolean[] items = this.items;
|
boolean[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
boolean temp = items[i];
|
boolean temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -297,7 +299,7 @@ public class BooleanArray {
|
||||||
/** Returns a random item from the array, or false if the array is empty. */
|
/** Returns a random item from the array, or false if the array is empty. */
|
||||||
public boolean random () {
|
public boolean random () {
|
||||||
if (size == 0) return false;
|
if (size == 0) return false;
|
||||||
return items[MathUtil.random(0, size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean[] toArray () {
|
public boolean[] toArray () {
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.Arrays;
|
||||||
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class ByteArray {
|
public class ByteArray {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
public byte[] items;
|
public byte[] items;
|
||||||
public int size;
|
public int size;
|
||||||
public boolean ordered;
|
public boolean ordered;
|
||||||
|
@ -326,7 +328,7 @@ public class ByteArray {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
byte[] items = this.items;
|
byte[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
byte temp = items[i];
|
byte temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -342,7 +344,7 @@ public class ByteArray {
|
||||||
/** Returns a random item from the array, or zero if the array is empty. */
|
/** Returns a random item from the array, or zero if the array is empty. */
|
||||||
public byte random () {
|
public byte random () {
|
||||||
if (size == 0) return 0;
|
if (size == 0) return 0;
|
||||||
return items[MathUtil.random(0, size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toArray () {
|
public byte[] toArray () {
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.Arrays;
|
||||||
* class avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
* class avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class CharArray {
|
public class CharArray {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
public char[] items;
|
public char[] items;
|
||||||
public int size;
|
public int size;
|
||||||
public boolean ordered;
|
public boolean ordered;
|
||||||
|
@ -326,7 +328,7 @@ public class CharArray {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
char[] items = this.items;
|
char[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
char temp = items[i];
|
char temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -342,7 +344,7 @@ public class CharArray {
|
||||||
/** Returns a random item from the array, or zero if the array is empty. */
|
/** Returns a random item from the array, or zero if the array is empty. */
|
||||||
public char random () {
|
public char random () {
|
||||||
if (size == 0) return 0;
|
if (size == 0) return 0;
|
||||||
return items[MathUtil.random(0, size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public char[] toArray () {
|
public char[] toArray () {
|
||||||
|
|
|
@ -13,30 +13,39 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package dorkbox.collections;
|
package dorkbox.collections
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
import java.util.Random;
|
object Collections {
|
||||||
|
/**
|
||||||
|
* Gets the version number.
|
||||||
|
*/
|
||||||
|
const val version = "1.0"
|
||||||
|
|
||||||
public
|
init {
|
||||||
class MathUtil {
|
// Add this project to the updates system, which verifies this class + UUID + version information
|
||||||
public static final Random random = new Random();
|
dorkbox.updates.Updates.add(java.util.Collections::class.java, "7a4be173d7fd48e4a09543cc572eb903", version)
|
||||||
|
|
||||||
/** Returns a random number between 0 (inclusive) and the specified value (inclusive). */
|
|
||||||
static public int random (int range) {
|
|
||||||
return random.nextInt(range + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a random number between start (inclusive) and end (inclusive). */
|
internal val random = Random()
|
||||||
static public int random (int start, int end) {
|
|
||||||
return start + random.nextInt(end - start + 1);
|
/** Returns a random number between 0 (inclusive) and the specified value (inclusive). */
|
||||||
|
fun random(range: Int): Int {
|
||||||
|
return random.nextInt(range + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a random number between start (inclusive) and end (inclusive). */
|
||||||
|
@JvmStatic
|
||||||
|
fun random(start: Int, end: Int): Int {
|
||||||
|
return start + random.nextInt(end - start + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the next power of two. Returns the specified value if the value is already a power of two.
|
* Returns the next power of two. Returns the specified value if the value is already a power of two.
|
||||||
*/
|
*/
|
||||||
public static
|
@JvmStatic
|
||||||
int nextPowerOfTwo(int value) {
|
fun nextPowerOfTwo(value: Int): Int {
|
||||||
return 1 << (32 - Integer.numberOfLeadingZeros(value - 1));
|
return 1 shl 32 - Integer.numberOfLeadingZeros(value - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ package dorkbox.collections;
|
||||||
* conjunction with a comparator that simply returns {@code ((Comparable)first).compareTo(Second)}. If this is the case, you are
|
* conjunction with a comparator that simply returns {@code ((Comparable)first).compareTo(Second)}. If this is the case, you are
|
||||||
* better off deleting ComparableTimSort to eliminate the code duplication. (See Arrays.java for details.) */
|
* better off deleting ComparableTimSort to eliminate the code duplication. (See Arrays.java for details.) */
|
||||||
class ComparableTimSort {
|
class ComparableTimSort {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
/** This is the minimum sized sequence that will be merged. Shorter sequences will be lengthened by calling binarySort. If the
|
/** This is the minimum sized sequence that will be merged. Shorter sequences will be lengthened by calling binarySort. If the
|
||||||
* entire array is less than this length, no merges will be performed.
|
* entire array is less than this length, no merges will be performed.
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,6 +25,8 @@ package dorkbox.collections;
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class ConcurrentEntry<T> {
|
class ConcurrentEntry<T> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private final T value;
|
private final T value;
|
||||||
|
|
||||||
private volatile ConcurrentEntry<T> next;
|
private volatile ConcurrentEntry<T> next;
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public
|
public
|
||||||
class ConcurrentIterator<T> {
|
class ConcurrentIterator<T> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the load-factor for the IdentityMap used
|
* Specifies the load-factor for the IdentityMap used
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,6 +36,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
* @author zhanhb
|
* @author zhanhb
|
||||||
*/
|
*/
|
||||||
class ConcurrentWeakIdentityHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
|
class ConcurrentWeakIdentityHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private final ConcurrentMap<Key<K>, V> map;
|
private final ConcurrentMap<Key<K>, V> map;
|
||||||
private final ReferenceQueue<K> queue = new ReferenceQueue<>();
|
private final ReferenceQueue<K> queue = new ReferenceQueue<>();
|
||||||
|
|
|
@ -19,12 +19,13 @@
|
||||||
package dorkbox.collections;
|
package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/** A resizable, ordered or unordered float array. Avoids the boxing that occurs with ArrayList<Float>. If unordered, this class
|
/** A resizable, ordered or unordered float array. Avoids the boxing that occurs with ArrayList<Float>. If unordered, this class
|
||||||
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class FloatArray {
|
public class FloatArray {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
public float[] items;
|
public float[] items;
|
||||||
public int size;
|
public int size;
|
||||||
public boolean ordered;
|
public boolean ordered;
|
||||||
|
@ -327,7 +328,7 @@ public class FloatArray {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
float[] items = this.items;
|
float[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
float temp = items[i];
|
float temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -343,7 +344,7 @@ public class FloatArray {
|
||||||
/** Returns a random item from the array, or zero if the array is empty. */
|
/** Returns a random item from the array, or zero if the array is empty. */
|
||||||
public float random () {
|
public float random () {
|
||||||
if (size == 0) return 0;
|
if (size == 0) return 0;
|
||||||
return items[MathUtil.random(0, size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] toArray () {
|
public float[] toArray () {
|
||||||
|
|
|
@ -31,6 +31,8 @@ import java.util.NoSuchElementException;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems"})
|
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems"})
|
||||||
public class IdentityMap<K, V> implements Iterable<IdentityMap.Entry<K, V>> {
|
public class IdentityMap<K, V> implements Iterable<IdentityMap.Entry<K, V>> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
|
@ -66,7 +68,7 @@ public class IdentityMap<K, V> implements Iterable<IdentityMap.Entry<K, V>> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public IdentityMap (int initialCapacity, float loadFactor) {
|
public IdentityMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -202,7 +204,7 @@ public class IdentityMap<K, V> implements Iterable<IdentityMap.Entry<K, V>> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random.nextInt(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -377,7 +379,7 @@ public class IdentityMap<K, V> implements Iterable<IdentityMap.Entry<K, V>> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,7 +470,7 @@ public class IdentityMap<K, V> implements Iterable<IdentityMap.Entry<K, V>> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.Arrays;
|
||||||
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class IntArray {
|
public class IntArray {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
public int[] items;
|
public int[] items;
|
||||||
public int size;
|
public int size;
|
||||||
public boolean ordered;
|
public boolean ordered;
|
||||||
|
@ -326,7 +328,7 @@ public class IntArray {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
int[] items = this.items;
|
int[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
int temp = items[i];
|
int temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -342,7 +344,7 @@ public class IntArray {
|
||||||
/** Returns a random item from the array, or zero if the array is empty. */
|
/** Returns a random item from the array, or zero if the array is empty. */
|
||||||
public int random () {
|
public int random () {
|
||||||
if (size == 0) return 0;
|
if (size == 0) return 0;
|
||||||
return items[MathUtil.random(0, size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] toArray () {
|
public int[] toArray () {
|
||||||
|
|
|
@ -30,7 +30,9 @@ import java.util.NoSuchElementException;
|
||||||
* next higher POT size.
|
* next higher POT size.
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class IntFloatMap implements Iterable<IntFloatMap.Entry> {
|
public class IntFloatMap implements Iterable<IntFloatMap.Entry> {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
private static final int EMPTY = 0;
|
private static final int EMPTY = 0;
|
||||||
|
@ -68,7 +70,7 @@ public class IntFloatMap implements Iterable<IntFloatMap.Entry> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public IntFloatMap (int initialCapacity, float loadFactor) {
|
public IntFloatMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -218,7 +220,7 @@ public class IntFloatMap implements Iterable<IntFloatMap.Entry> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -424,7 +426,7 @@ public class IntFloatMap implements Iterable<IntFloatMap.Entry> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +508,7 @@ public class IntFloatMap implements Iterable<IntFloatMap.Entry> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -29,7 +29,9 @@ import java.util.NoSuchElementException;
|
||||||
* next higher POT size.
|
* next higher POT size.
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class IntIntMap implements Iterable<IntIntMap.Entry> {
|
public class IntIntMap implements Iterable<IntIntMap.Entry> {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
private static final int EMPTY = 0;
|
private static final int EMPTY = 0;
|
||||||
|
@ -66,7 +68,7 @@ public class IntIntMap implements Iterable<IntIntMap.Entry> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public IntIntMap (int initialCapacity, float loadFactor) {
|
public IntIntMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -216,7 +218,7 @@ public class IntIntMap implements Iterable<IntIntMap.Entry> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -422,7 +424,7 @@ public class IntIntMap implements Iterable<IntIntMap.Entry> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +494,7 @@ public class IntIntMap implements Iterable<IntIntMap.Entry> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/** An unordered map that uses int keys. This implementation is a cuckoo hash map using 3 hashes, random walking, and a small
|
/** An unordered map that uses int keys. This implementation is a cuckoo hash map using 3 hashes, random walking, and a small
|
||||||
* stash for problematic keys. Null values are allowed. No allocation is done except when growing the table size. <br>
|
* stash for problematic keys. Null values are allowed. No allocation is done except when growing the table size. <br>
|
||||||
|
@ -31,6 +30,8 @@ import java.util.Random;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public class IntMap<V> implements Iterable<IntMap.Entry<V>> {
|
public class IntMap<V> implements Iterable<IntMap.Entry<V>> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
|
@ -69,7 +70,7 @@ public class IntMap<V> implements Iterable<IntMap.Entry<V>> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public IntMap (int initialCapacity, float loadFactor) {
|
public IntMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -226,7 +227,7 @@ public class IntMap<V> implements Iterable<IntMap.Entry<V>> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random.nextInt(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -414,7 +415,7 @@ public class IntMap<V> implements Iterable<IntMap.Entry<V>> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +516,7 @@ public class IntMap<V> implements Iterable<IntMap.Entry<V>> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
package dorkbox.collections;
|
package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/** An unordered set that uses int keys. This implementation uses cuckoo hashing using 3 hashes, random walking, and a small stash
|
/** An unordered set that uses int keys. This implementation uses cuckoo hashing using 3 hashes, random walking, and a small stash
|
||||||
* for problematic keys. No allocation is done except when growing the table size. <br>
|
* for problematic keys. No allocation is done except when growing the table size. <br>
|
||||||
|
@ -29,7 +28,9 @@ import java.util.Random;
|
||||||
* size.
|
* size.
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class IntSet {
|
public class IntSet {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
private static final int EMPTY = 0;
|
private static final int EMPTY = 0;
|
||||||
|
@ -63,7 +64,7 @@ public class IntSet {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public IntSet (int initialCapacity, float loadFactor) {
|
public IntSet (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -211,7 +212,7 @@ public class IntSet {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random.nextInt(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
keyTable[index1] = insertKey;
|
keyTable[index1] = insertKey;
|
||||||
|
@ -336,7 +337,7 @@ public class IntSet {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +395,7 @@ public class IntSet {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -39,6 +39,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
|
class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeArrayList, ArrayList> listRef =
|
private static final AtomicReferenceFieldUpdater<LockFreeArrayList, ArrayList> listRef =
|
||||||
AtomicReferenceFieldUpdater.newUpdater(LockFreeArrayList.class,
|
AtomicReferenceFieldUpdater.newUpdater(LockFreeArrayList.class,
|
||||||
|
@ -107,9 +109,9 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public
|
public
|
||||||
E get(int index) {
|
E get(int index) {
|
||||||
//noinspection unchecked
|
|
||||||
return (E) listRef.get(this).get(index);
|
return (E) listRef.get(this).get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +158,7 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
|
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
ListIterator<E> listIterator() {
|
ListIterator<E> listIterator() {
|
||||||
|
@ -163,6 +166,7 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
ListIterator<E> listIterator(final int index) {
|
ListIterator<E> listIterator(final int index) {
|
||||||
|
@ -170,6 +174,7 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
List<E> subList(final int startIndex, final int endIndex) {
|
List<E> subList(final int startIndex, final int endIndex) {
|
||||||
|
@ -185,10 +190,10 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
boolean containsAll(final Collection<?> collection) {
|
boolean containsAll(final Collection<?> collection) {
|
||||||
//noinspection unchecked
|
|
||||||
return listRef.get(this).containsAll(collection);
|
return listRef.get(this).containsAll(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,6 +218,7 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
Iterator<E> iterator() {
|
Iterator<E> iterator() {
|
||||||
|
@ -227,10 +233,10 @@ class LockFreeArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializ
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
<T> T[] toArray(final T[] targetArray) {
|
<T> T[] toArray(final T[] targetArray) {
|
||||||
//noinspection unchecked
|
|
||||||
return (T[]) listRef.get(this).toArray(targetArray);
|
return (T[]) listRef.get(this).toArray(targetArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public final
|
public final
|
||||||
class LockFreeBiMap<K, V> {
|
class LockFreeBiMap<K, V> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeBiMap, HashMap> forwardREF =
|
private static final AtomicReferenceFieldUpdater<LockFreeBiMap, HashMap> forwardREF =
|
||||||
AtomicReferenceFieldUpdater.newUpdater(LockFreeBiMap.class,
|
AtomicReferenceFieldUpdater.newUpdater(LockFreeBiMap.class,
|
||||||
|
|
|
@ -39,6 +39,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
class LockFreeHashMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
class LockFreeHashMap<K, V> implements Map<K, V>, Cloneable, Serializable {
|
||||||
|
public static final String version = dorkbox.collections.Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeHashMap, HashMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeHashMap, HashMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeHashMap.class,
|
LockFreeHashMap.class,
|
||||||
|
|
|
@ -38,6 +38,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
class LockFreeHashSet<E> implements Set<E>, Cloneable, Serializable {
|
class LockFreeHashSet<E> implements Set<E>, Cloneable, Serializable {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeHashSet, Set> setREF =
|
private static final AtomicReferenceFieldUpdater<LockFreeHashSet, Set> setREF =
|
||||||
AtomicReferenceFieldUpdater.newUpdater(LockFreeHashSet.class,
|
AtomicReferenceFieldUpdater.newUpdater(LockFreeHashSet.class,
|
||||||
|
@ -71,6 +73,7 @@ class LockFreeHashSet<E> implements Set<E>, Cloneable, Serializable {
|
||||||
return hashSet.add(element);
|
return hashSet.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
boolean containsAll(final Collection<?> collection) {
|
boolean containsAll(final Collection<?> collection) {
|
||||||
|
@ -133,10 +136,10 @@ class LockFreeHashSet<E> implements Set<E>, Cloneable, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
Iterator<E> iterator() {
|
Iterator<E> iterator() {
|
||||||
//noinspection unchecked
|
|
||||||
return setREF.get(this).iterator();
|
return setREF.get(this).iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,10 +151,10 @@ class LockFreeHashSet<E> implements Set<E>, Cloneable, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock-free get
|
// lock-free get
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
<T> T[] toArray(final T[] targetArray) {
|
<T> T[] toArray(final T[] targetArray) {
|
||||||
//noinspection unchecked
|
|
||||||
return (T[]) setREF.get(this).toArray(targetArray);
|
return (T[]) setREF.get(this).toArray(targetArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class LockFreeIntBiMap<V> {
|
class LockFreeIntBiMap<V> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeIntBiMap, IntMap> forwardREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeIntBiMap, IntMap> forwardREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeIntBiMap.class,
|
LockFreeIntBiMap.class,
|
||||||
|
|
|
@ -45,6 +45,8 @@ import dorkbox.collections.IntMap.*;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final
|
public final
|
||||||
class LockFreeIntMap<V> implements Cloneable, Serializable {
|
class LockFreeIntMap<V> implements Cloneable, Serializable {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeIntMap, IntMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeIntMap, IntMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeIntMap.class,
|
LockFreeIntMap.class,
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public
|
public
|
||||||
class LockFreeIntStringMap<V> {
|
class LockFreeIntStringMap<V> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeIntStringMap, IntMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeIntStringMap, IntMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeIntStringMap.class,
|
LockFreeIntStringMap.class,
|
||||||
IntMap.class,
|
IntMap.class,
|
||||||
|
|
|
@ -40,6 +40,8 @@ import dorkbox.collections.IntMap.*;
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class LockFreeObjectIntBiMap<V> {
|
class LockFreeObjectIntBiMap<V> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeObjectIntBiMap, ObjectIntMap> forwardREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeObjectIntBiMap, ObjectIntMap> forwardREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeObjectIntBiMap.class,
|
LockFreeObjectIntBiMap.class,
|
||||||
|
|
|
@ -34,6 +34,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class LockFreeObjectIntMap<V> {
|
class LockFreeObjectIntMap<V> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeObjectIntMap, ObjectIntMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeObjectIntMap, ObjectIntMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeObjectIntMap.class,
|
LockFreeObjectIntMap.class,
|
||||||
|
|
|
@ -34,6 +34,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final
|
public final
|
||||||
class LockFreeObjectMap<K, V> implements Cloneable, Serializable {
|
class LockFreeObjectMap<K, V> implements Cloneable, Serializable {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeObjectMap, ObjectMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
private static final AtomicReferenceFieldUpdater<LockFreeObjectMap, ObjectMap> mapREF = AtomicReferenceFieldUpdater.newUpdater(
|
||||||
LockFreeObjectMap.class,
|
LockFreeObjectMap.class,
|
||||||
|
|
|
@ -38,6 +38,8 @@ import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final
|
public final
|
||||||
class LockFreeSet<E> implements Set<E>, Cloneable, java.io.Serializable {
|
class LockFreeSet<E> implements Set<E>, Cloneable, java.io.Serializable {
|
||||||
|
public static final String version = dorkbox.collections.Collections.version;
|
||||||
|
|
||||||
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
// Recommended for best performance while adhering to the "single writer principle". Must be static-final
|
||||||
private static final AtomicReferenceFieldUpdater<LockFreeSet, Set> setREF = AtomicReferenceFieldUpdater.newUpdater(LockFreeSet.class,
|
private static final AtomicReferenceFieldUpdater<LockFreeSet, Set> setREF = AtomicReferenceFieldUpdater.newUpdater(LockFreeSet.class,
|
||||||
Set.class,
|
Set.class,
|
||||||
|
|
|
@ -24,7 +24,9 @@ import java.util.Arrays;
|
||||||
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
* avoids a memory copy when removing elements (the last element is moved to the removed element's position).
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
public class LongArray {
|
public class LongArray {
|
||||||
public long[] items;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
public long[] items;
|
||||||
public int size;
|
public int size;
|
||||||
public boolean ordered;
|
public boolean ordered;
|
||||||
|
|
||||||
|
@ -326,7 +328,7 @@ public class LongArray {
|
||||||
public void shuffle () {
|
public void shuffle () {
|
||||||
long[] items = this.items;
|
long[] items = this.items;
|
||||||
for (int i = size - 1; i >= 0; i--) {
|
for (int i = size - 1; i >= 0; i--) {
|
||||||
int ii = MathUtil.random(i);
|
int ii = Collections.INSTANCE.random(i);
|
||||||
long temp = items[i];
|
long temp = items[i];
|
||||||
items[i] = items[ii];
|
items[i] = items[ii];
|
||||||
items[ii] = temp;
|
items[ii] = temp;
|
||||||
|
@ -342,7 +344,7 @@ public class LongArray {
|
||||||
/** Returns a random item from the array, or zero if the array is empty. */
|
/** Returns a random item from the array, or zero if the array is empty. */
|
||||||
public long random () {
|
public long random () {
|
||||||
if (size == 0) return 0;
|
if (size == 0) return 0;
|
||||||
return items[MathUtil.random(0,size - 1)];
|
return items[Collections.random(0, size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public long[] toArray () {
|
public long[] toArray () {
|
||||||
|
|
|
@ -30,7 +30,9 @@ import java.util.NoSuchElementException;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"NullableProblems", "rawtypes", "unchecked"})
|
@SuppressWarnings({"NullableProblems", "rawtypes", "unchecked"})
|
||||||
public class LongMap<V> implements Iterable<LongMap.Entry<V>> {
|
public class LongMap<V> implements Iterable<LongMap.Entry<V>> {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
private static final int EMPTY = 0;
|
private static final int EMPTY = 0;
|
||||||
|
@ -68,7 +70,7 @@ public class LongMap<V> implements Iterable<LongMap.Entry<V>> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public LongMap (int initialCapacity, float loadFactor) {
|
public LongMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -224,7 +226,7 @@ public class LongMap<V> implements Iterable<LongMap.Entry<V>> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -412,7 +414,7 @@ public class LongMap<V> implements Iterable<LongMap.Entry<V>> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +513,7 @@ public class LongMap<V> implements Iterable<LongMap.Entry<V>> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
|
|
||||||
/** An unordered map where the values are floats. This implementation is a cuckoo hash map using 3 hashes, random walking, and a
|
/** An unordered map where the values are floats. This implementation is a cuckoo hash map using 3 hashes, random walking, and a
|
||||||
|
@ -32,7 +31,9 @@ import java.util.Random;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "NullableProblems", "rawtypes"})
|
@SuppressWarnings({"unchecked", "NullableProblems", "rawtypes"})
|
||||||
public class ObjectFloatMap<K> implements Iterable<ObjectFloatMap.Entry<K>> {
|
public class ObjectFloatMap<K> implements Iterable<ObjectFloatMap.Entry<K>> {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ public class ObjectFloatMap<K> implements Iterable<ObjectFloatMap.Entry<K>> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ObjectFloatMap (int initialCapacity, float loadFactor) {
|
public ObjectFloatMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -204,7 +205,7 @@ public class ObjectFloatMap<K> implements Iterable<ObjectFloatMap.Entry<K>> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -392,7 +393,7 @@ public class ObjectFloatMap<K> implements Iterable<ObjectFloatMap.Entry<K>> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +461,7 @@ public class ObjectFloatMap<K> implements Iterable<ObjectFloatMap.Entry<K>> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
|
|
||||||
/** An unordered map where the values are ints. This implementation is a cuckoo hash map using 3 hashes, random walking, and a
|
/** An unordered map where the values are ints. This implementation is a cuckoo hash map using 3 hashes, random walking, and a
|
||||||
|
@ -32,6 +31,8 @@ import java.util.Random;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "NullableProblems"})
|
@SuppressWarnings({"unchecked", "NullableProblems"})
|
||||||
public class ObjectIntMap<K> implements Iterable<ObjectIntMap.Entry<K>> {
|
public class ObjectIntMap<K> implements Iterable<ObjectIntMap.Entry<K>> {
|
||||||
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
|
@ -67,7 +68,7 @@ public class ObjectIntMap<K> implements Iterable<ObjectIntMap.Entry<K>> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public ObjectIntMap (int initialCapacity, float loadFactor) {
|
public ObjectIntMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -203,7 +204,7 @@ public class ObjectIntMap<K> implements Iterable<ObjectIntMap.Entry<K>> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -391,7 +392,7 @@ public class ObjectIntMap<K> implements Iterable<ObjectIntMap.Entry<K>> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,7 +461,7 @@ public class ObjectIntMap<K> implements Iterable<ObjectIntMap.Entry<K>> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/** An unordered map. This implementation is a cuckoo hash map using 3 hashes, random walking, and a small stash for problematic
|
/** An unordered map. This implementation is a cuckoo hash map using 3 hashes, random walking, and a small stash for problematic
|
||||||
* keys. Null keys are not allowed. Null values are allowed. No allocation is done except when growing the table size. <br>
|
* keys. Null keys are not allowed. Null values are allowed. No allocation is done except when growing the table size. <br>
|
||||||
|
@ -34,7 +33,9 @@ import java.util.Random;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class ObjectMap<K, V> implements Iterable<ObjectMap.Entry<K, V>> {
|
public class ObjectMap<K, V> implements Iterable<ObjectMap.Entry<K, V>> {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public class ObjectMap<K, V> implements Iterable<ObjectMap.Entry<K, V>> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public ObjectMap (int initialCapacity, float loadFactor) {
|
public ObjectMap (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ public class ObjectMap<K, V> implements Iterable<ObjectMap.Entry<K, V>> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random.nextInt(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
evictedValue = valueTable[index1];
|
evictedValue = valueTable[index1];
|
||||||
|
@ -393,7 +394,7 @@ public class ObjectMap<K, V> implements Iterable<ObjectMap.Entry<K, V>> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,7 +488,7 @@ public class ObjectMap<K, V> implements Iterable<ObjectMap.Entry<K, V>> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ package dorkbox.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
|
|
||||||
/** An unordered set where the keys are objects. This implementation uses cuckoo hashing using 3 hashes, random walking, and a
|
/** An unordered set where the keys are objects. This implementation uses cuckoo hashing using 3 hashes, random walking, and a
|
||||||
|
@ -35,7 +34,9 @@ import java.util.Random;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems", "SuspiciousSystemArraycopy"})
|
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems", "SuspiciousSystemArraycopy"})
|
||||||
public class ObjectSet<T> implements Iterable<T> {
|
public class ObjectSet<T> implements Iterable<T> {
|
||||||
private static final int PRIME1 = 0xbe1f14b1;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static final int PRIME1 = 0xbe1f14b1;
|
||||||
private static final int PRIME2 = 0xb4b82e39;
|
private static final int PRIME2 = 0xb4b82e39;
|
||||||
private static final int PRIME3 = 0xced1c241;
|
private static final int PRIME3 = 0xced1c241;
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ public class ObjectSet<T> implements Iterable<T> {
|
||||||
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
* @param initialCapacity If not a power of two, it is increased to the next nearest power of two. */
|
||||||
public ObjectSet (int initialCapacity, float loadFactor) {
|
public ObjectSet (int initialCapacity, float loadFactor) {
|
||||||
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity must be >= 0: " + initialCapacity);
|
||||||
initialCapacity = MathUtil.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
initialCapacity = Collections.nextPowerOfTwo((int)Math.ceil(initialCapacity / loadFactor));
|
||||||
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
if (initialCapacity > 1 << 30) throw new IllegalArgumentException("initialCapacity is too large: " + initialCapacity);
|
||||||
capacity = initialCapacity;
|
capacity = initialCapacity;
|
||||||
|
|
||||||
|
@ -204,7 +205,7 @@ public class ObjectSet<T> implements Iterable<T> {
|
||||||
int i = 0, pushIterations = this.pushIterations;
|
int i = 0, pushIterations = this.pushIterations;
|
||||||
do {
|
do {
|
||||||
// Replace the key and value for one of the hashes.
|
// Replace the key and value for one of the hashes.
|
||||||
switch (MathUtil.random.nextInt(2)) {
|
switch (Collections.INSTANCE.random(2)) {
|
||||||
case 0:
|
case 0:
|
||||||
evictedKey = key1;
|
evictedKey = key1;
|
||||||
keyTable[index1] = insertKey;
|
keyTable[index1] = insertKey;
|
||||||
|
@ -327,7 +328,7 @@ public class ObjectSet<T> implements Iterable<T> {
|
||||||
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
|
||||||
if (size > maximumCapacity) maximumCapacity = size;
|
if (size > maximumCapacity) maximumCapacity = size;
|
||||||
if (capacity <= maximumCapacity) return;
|
if (capacity <= maximumCapacity) return;
|
||||||
maximumCapacity = MathUtil.nextPowerOfTwo(maximumCapacity);
|
maximumCapacity = Collections.nextPowerOfTwo(maximumCapacity);
|
||||||
resize(maximumCapacity);
|
resize(maximumCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +403,7 @@ public class ObjectSet<T> implements Iterable<T> {
|
||||||
public void ensureCapacity (int additionalCapacity) {
|
public void ensureCapacity (int additionalCapacity) {
|
||||||
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
if (additionalCapacity < 0) throw new IllegalArgumentException("additionalCapacity must be >= 0: " + additionalCapacity);
|
||||||
int sizeNeeded = size + additionalCapacity;
|
int sizeNeeded = size + additionalCapacity;
|
||||||
if (sizeNeeded >= threshold) resize(MathUtil.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
if (sizeNeeded >= threshold) resize(Collections.nextPowerOfTwo((int)Math.ceil(sizeNeeded / loadFactor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resize (int newSize) {
|
private void resize (int newSize) {
|
||||||
|
|
|
@ -28,7 +28,9 @@ import java.util.NoSuchElementException;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "NullableProblems"})
|
@SuppressWarnings({"unchecked", "NullableProblems"})
|
||||||
public class OrderedMap<K, V> extends ObjectMap<K, V> {
|
public class OrderedMap<K, V> extends ObjectMap<K, V> {
|
||||||
final Array<K> keys;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
final Array<K> keys;
|
||||||
|
|
||||||
private Entries entries1, entries2;
|
private Entries entries1, entries2;
|
||||||
private Values values1, values2;
|
private Values values1, values2;
|
||||||
|
|
|
@ -28,7 +28,9 @@ import java.util.NoSuchElementException;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public class OrderedSet<T> extends ObjectSet<T> {
|
public class OrderedSet<T> extends ObjectSet<T> {
|
||||||
final Array<T> items;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
final Array<T> items;
|
||||||
OrderedSetIterator iterator1, iterator2;
|
OrderedSetIterator iterator1, iterator2;
|
||||||
|
|
||||||
public OrderedSet () {
|
public OrderedSet () {
|
||||||
|
|
|
@ -25,7 +25,9 @@ import java.util.Comparator;
|
||||||
* http://en.wikipedia.org/wiki/Quickselect
|
* http://en.wikipedia.org/wiki/Quickselect
|
||||||
* @author Jon Renner */
|
* @author Jon Renner */
|
||||||
public class QuickSelect<T> {
|
public class QuickSelect<T> {
|
||||||
private T[] array;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private T[] array;
|
||||||
private Comparator<? super T> comp;
|
private Comparator<? super T> comp;
|
||||||
|
|
||||||
public int select (T[] items, Comparator<T> comp, int n, int size) {
|
public int select (T[] items, Comparator<T> comp, int n, int size) {
|
||||||
|
|
|
@ -34,7 +34,9 @@ import java.util.Comparator;
|
||||||
* @author Jon Renner */
|
* @author Jon Renner */
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class Select {
|
public class Select {
|
||||||
private static Select instance;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
private static Select instance;
|
||||||
private QuickSelect quickSelect;
|
private QuickSelect quickSelect;
|
||||||
|
|
||||||
/** Provided for convenience */
|
/** Provided for convenience */
|
||||||
|
|
|
@ -23,7 +23,9 @@ import java.util.Comparator;
|
||||||
* @author Nathan Sweet */
|
* @author Nathan Sweet */
|
||||||
@SuppressWarnings({"RedundantCast", "unchecked", "rawtypes"})
|
@SuppressWarnings({"RedundantCast", "unchecked", "rawtypes"})
|
||||||
public class Sort {
|
public class Sort {
|
||||||
static private Sort instance;
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
static private Sort instance;
|
||||||
|
|
||||||
private TimSort timSort;
|
private TimSort timSort;
|
||||||
private ComparableTimSort comparableTimSort;
|
private ComparableTimSort comparableTimSort;
|
||||||
|
|
|
@ -39,7 +39,9 @@ import java.util.Comparator;
|
||||||
* in place, using a binary insertion sort. */
|
* in place, using a binary insertion sort. */
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
class TimSort<T> {
|
class TimSort<T> {
|
||||||
/** This is the minimum sized sequence that will be merged. Shorter sequences will be lengthened by calling binarySort. If the
|
public static final String version = Collections.version;
|
||||||
|
|
||||||
|
/** This is the minimum sized sequence that will be merged. Shorter sequences will be lengthened by calling binarySort. If the
|
||||||
* entire array is less than this length, no merges will be performed.
|
* entire array is less than this length, no merges will be performed.
|
||||||
*
|
*
|
||||||
* This constant should be a power of two. It was 64 in Tim Peter's C implementation, but 32 was empirically determined to work
|
* This constant should be a power of two. It was 64 in Tim Peter's C implementation, but 32 was empirically determined to work
|
||||||
|
|
Loading…
Reference in New Issue