package com.carrotsearch.hppc;
public final class HashContainers {
public final static int MAX_HASH_ARRAY_LENGTH = 0x80000000 >>> 1;
public final static int MIN_HASH_ARRAY_LENGTH = 4;
public final static float DEFAULT_LOAD_FACTOR = 0.75f;
public final static float MIN_LOAD_FACTOR = 1 / 100.0f;
public final static float MAX_LOAD_FACTOR = 99 / 100.0f;
public static int maxElements(double loadFactor) {
checkLoadFactor(loadFactor, 0, 1);
return expandAtCount(MAX_HASH_ARRAY_LENGTH, loadFactor) - 1;
}
static int minBufferSize(int elements, double loadFactor) {
if (elements < 0) {
throw new IllegalArgumentException(
"Number of elements must be >= 0: " + elements);
}
long length = (long) Math.ceil(elements / loadFactor);
if (length == elements) {
length++;
}
length = Math.max(MIN_HASH_ARRAY_LENGTH, BitUtil.nextHighestPowerOfTwo(length));
if (length > MAX_HASH_ARRAY_LENGTH) {
throw new BufferAllocationException(
"Maximum array size exceeded for this load factor (elements: %d, load factor: %f)",
elements,
loadFactor);
}
return (int) length;
}
static int nextBufferSize(int arraySize, int elements, double loadFactor) {
assert checkPowerOfTwo(arraySize);
if (arraySize == MAX_HASH_ARRAY_LENGTH) {
throw new BufferAllocationException(
"Maximum array size exceeded for this load factor (elements: %d, load factor: %f)",
elements,
loadFactor);
}
return (int) arraySize << 1;
}
static int expandAtCount(int arraySize, double loadFactor) {
assert checkPowerOfTwo(arraySize);
return Math.min(arraySize - 1, (int) Math.ceil(arraySize * loadFactor));
}
static void checkLoadFactor(double loadFactor, double minAllowedInclusive, double maxAllowedInclusive) {
if (loadFactor < minAllowedInclusive || loadFactor > maxAllowedInclusive) {
throw new BufferAllocationException(
"The load factor should be in range [%.2f, %.2f]: %f",
minAllowedInclusive,
maxAllowedInclusive,
loadFactor);
}
}
static boolean checkPowerOfTwo(int arraySize) {
assert arraySize > 1;
assert BitUtil.nextHighestPowerOfTwo(arraySize) == arraySize;
return true;
}
}