mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-140 Prevent MultiMaps from occasionally being too dense
This commit is contained in:
@@ -27,6 +27,17 @@ import net.openhft.lang.io.DirectStore;
|
||||
*/
|
||||
class VanillaIntIntMultiMap implements IntIntMultiMap {
|
||||
|
||||
static int multiMapCapacity(int minCapacity) {
|
||||
if (minCapacity < 0)
|
||||
throw new IllegalArgumentException();
|
||||
int capacity = Maths.nextPower2(minCapacity, 16);
|
||||
if (((double) minCapacity) / capacity > 2./3.) {
|
||||
// multi map shouldn't be too dense
|
||||
capacity <<= 1;
|
||||
}
|
||||
return capacity;
|
||||
}
|
||||
|
||||
private static final int ENTRY_SIZE = 8;
|
||||
private static final int ENTRY_SIZE_SHIFT = 3;
|
||||
private static final int UNSET_KEY = 0;
|
||||
@@ -50,9 +61,7 @@ class VanillaIntIntMultiMap implements IntIntMultiMap {
|
||||
private long searchPos = -1L;
|
||||
|
||||
public VanillaIntIntMultiMap(int minCapacity) {
|
||||
if (minCapacity < 0)
|
||||
throw new IllegalArgumentException();
|
||||
capacity = Maths.nextPower2(minCapacity, 16);
|
||||
capacity = multiMapCapacity(minCapacity);
|
||||
capacityMask = capacity - 1;
|
||||
capacityMask2 = indexToPos(capacity - 1);
|
||||
bytes = DirectStore.allocateLazy(indexToPos(capacity)).bytes();
|
||||
@@ -75,7 +84,7 @@ class VanillaIntIntMultiMap implements IntIntMultiMap {
|
||||
* constructor as the first argument
|
||||
*/
|
||||
public static long sizeInBytes(int minCapacity) {
|
||||
return indexToPos(Maths.nextPower2(minCapacity, 16));
|
||||
return indexToPos(multiMapCapacity(minCapacity));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +93,7 @@ class VanillaIntIntMultiMap implements IntIntMultiMap {
|
||||
* constructor as the second argument
|
||||
*/
|
||||
public static long sizeOfBitSetInBytes(int minCapacity) {
|
||||
return Maths.nextPower2(minCapacity, 64L) / 8L;
|
||||
return Math.max(multiMapCapacity(minCapacity), 64L) / 8L;
|
||||
}
|
||||
|
||||
public static ATSDirectBitSet newPositions(int capacity) {
|
||||
|
||||
@@ -23,6 +23,8 @@ import net.openhft.lang.collection.DirectBitSet;
|
||||
import net.openhft.lang.io.Bytes;
|
||||
import net.openhft.lang.io.DirectStore;
|
||||
|
||||
import static net.openhft.chronicle.map.VanillaIntIntMultiMap.multiMapCapacity;
|
||||
|
||||
/**
|
||||
* Supports a simple interface for int -> int[] off heap.
|
||||
*/
|
||||
@@ -43,9 +45,9 @@ class VanillaShortShortMultiMap implements IntIntMultiMap {
|
||||
private int searchPos = -1;
|
||||
|
||||
public VanillaShortShortMultiMap(int minCapacity) {
|
||||
if (minCapacity < 0 || minCapacity > (1 << 16))
|
||||
capacity = multiMapCapacity(minCapacity);
|
||||
if (capacity > (1 << 16))
|
||||
throw new IllegalArgumentException();
|
||||
capacity = Maths.nextPower2(minCapacity, 16);
|
||||
capacityMask = capacity - 1;
|
||||
capacityMask2 = (capacity - 1) * ENTRY_SIZE;
|
||||
bytes = DirectStore.allocateLazy(capacity * ENTRY_SIZE).bytes();
|
||||
@@ -68,7 +70,7 @@ class VanillaShortShortMultiMap implements IntIntMultiMap {
|
||||
* constructor as the first argument
|
||||
*/
|
||||
public static long sizeInBytes(int minCapacity) {
|
||||
return Maths.nextPower2(minCapacity, 16L) * ENTRY_SIZE;
|
||||
return ((long) multiMapCapacity(minCapacity)) * ENTRY_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user