add maxCapacity to LongLongHashMap

This allows us to define an upper limit for the memory usage.
This commit is contained in:
2021-04-16 17:52:15 +02:00
parent 9de619d815
commit 062d63ca02
3 changed files with 88 additions and 10 deletions

View File

@@ -46,6 +46,8 @@ public class LongLongHashMap {
*/
private Long removedKeyValue = null;
private int maxCapacity = MAX_ARRAY_SIZE;
/**
* Create a new {@link LongLongHashMap} with the given initial capacity and load
* factor.
@@ -78,6 +80,30 @@ public class LongLongHashMap {
this(8, 0.75);
}
/**
* Sets the maximum capacity.<p>
* This restricts the maximum memory used by this map. The memory consumption can be twice as much during grow or shrink phases.
* <p>
* Note that the performance can suffer if the map contains more keys than capacity time loadFactor.
* <p>
* Note an automatic {@link #rehash()} is triggered if the new maxCapacity is smaller than the current capacity.
* But there is not automatic rehash when the new maxCapacity is greater than the current capacity.
*
* @param maxCapacity new maximum capacity
* @throws IllegalArgumentException if {@code maxCapacity} is smaller than {@link #size()}
*/
public void setMaxCapacity(int maxCapacity) {
if (maxCapacity < size) {
throw new IllegalArgumentException("maxCapacity must equal or larger than current size of the map");
}
this.maxCapacity = maxCapacity;
if (maxCapacity < keys.length) {
rehash(maxCapacity);
}
}
/**
* The number of entries in this map.
*
@@ -144,9 +170,14 @@ public class LongLongHashMap {
*
* @param key the key
* @param value the value
* @throws IllegalStateException if the map is full, see {@link #setMaxCapacity(int)}
*/
public void put(final long key, final long value) {
if (size == maxCapacity) {
throw new IllegalStateException("map is full");
}
if (key == NULL_KEY) {
size += zeroValue == null ? 1 : 0;
zeroValue = value;
@@ -448,8 +479,10 @@ public class LongLongHashMap {
}
private void growAndRehash() {
final int newSize = Math.min(keys.length * 2, MAX_ARRAY_SIZE);
rehash(newSize);
final int newSize = Math.min(keys.length * 2, maxCapacity);
if(newSize != keys.length) {
rehash(newSize);
}
}
private void rehash(int newSize) {