/** Skips checks for existing keys. */ private void putResize(K key, float value) { // Check for empty buckets. int hashCode = key.hashCode(); int index1 = hashCode & mask; K key1 = keyTable[index1]; if (key1 == null) { keyTable[index1] = key; valueTable[index1] = value; if (size++ >= threshold) resize(capacity << 1); return; } int index2 = hash2(hashCode); K key2 = keyTable[index2]; if (key2 == null) { keyTable[index2] = key; valueTable[index2] = value; if (size++ >= threshold) resize(capacity << 1); return; } int index3 = hash3(hashCode); K key3 = keyTable[index3]; if (key3 == null) { keyTable[index3] = key; valueTable[index3] = value; if (size++ >= threshold) resize(capacity << 1); return; } push(key, value, index1, key1, index2, key2, index3, key3); }
public void put(K key, float value) { if (key == null) throw new IllegalArgumentException("key cannot be null."); K[] keyTable = this.keyTable; // Check for existing keys. int hashCode = key.hashCode(); int index1 = hashCode & mask; K key1 = keyTable[index1]; if (key.equals(key1)) { valueTable[index1] = value; return; } int index2 = hash2(hashCode); K key2 = keyTable[index2]; if (key.equals(key2)) { valueTable[index2] = value; return; } int index3 = hash3(hashCode); K key3 = keyTable[index3]; if (key.equals(key3)) { valueTable[index3] = value; return; } // Update key in the stash. for (int i = capacity, n = i + stashSize; i < n; i++) { if (key.equals(keyTable[i])) { valueTable[i] = value; return; } } // Check for empty buckets. if (key1 == null) { keyTable[index1] = key; valueTable[index1] = value; if (size++ >= threshold) resize(capacity << 1); return; } if (key2 == null) { keyTable[index2] = key; valueTable[index2] = value; if (size++ >= threshold) resize(capacity << 1); return; } if (key3 == null) { keyTable[index3] = key; valueTable[index3] = value; if (size++ >= threshold) resize(capacity << 1); return; } push(key, value, index1, key1, index2, key2, index3, key3); }
/** * Clears the map and reduces the size of the backing arrays to be the specified capacity if they * are larger. */ public void clear(int maximumCapacity) { if (capacity <= maximumCapacity) { clear(); return; } size = 0; resize(maximumCapacity); }
/** * Reduces the size of the backing arrays to be the specified capacity or less. If the capacity is * already less, nothing is done. If the map contains more items than the specified capacity, the * next highest power of two capacity is used instead. */ public void shrink(int maximumCapacity) { if (maximumCapacity < 0) throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity); if (size > maximumCapacity) maximumCapacity = size; if (capacity <= maximumCapacity) return; maximumCapacity = MathUtils.nextPowerOfTwo(maximumCapacity); resize(maximumCapacity); }
private void putStash(K key, float value) { if (stashSize == stashCapacity) { // Too many pushes occurred and the stash is full, increase the table size. resize(capacity << 1); put(key, value); return; } // Store key in the stash. int index = capacity + stashSize; keyTable[index] = key; valueTable[index] = value; stashSize++; size++; }
/** * Increases the size of the backing array to accommodate the specified number of additional * items. Useful before adding many items to avoid multiple backing array resizes. */ public void ensureCapacity(int additionalCapacity) { int sizeNeeded = size + additionalCapacity; if (sizeNeeded >= threshold) resize(MathUtils.nextPowerOfTwo((int) (sizeNeeded / loadFactor))); }
private void push( K insertKey, float insertValue, int index1, K key1, int index2, K key2, int index3, K key3) { K[] keyTable = this.keyTable; float[] valueTable = this.valueTable; int mask = this.mask; // Push keys until an empty bucket is found. K evictedKey; float evictedValue; int i = 0, pushIterations = this.pushIterations; do { // Replace the key and value for one of the hashes. switch (MathUtils.random(2)) { case 0: evictedKey = key1; evictedValue = valueTable[index1]; keyTable[index1] = insertKey; valueTable[index1] = insertValue; break; case 1: evictedKey = key2; evictedValue = valueTable[index2]; keyTable[index2] = insertKey; valueTable[index2] = insertValue; break; default: evictedKey = key3; evictedValue = valueTable[index3]; keyTable[index3] = insertKey; valueTable[index3] = insertValue; break; } // If the evicted key hashes to an empty bucket, put it there and stop. int hashCode = evictedKey.hashCode(); index1 = hashCode & mask; key1 = keyTable[index1]; if (key1 == null) { keyTable[index1] = evictedKey; valueTable[index1] = evictedValue; if (size++ >= threshold) resize(capacity << 1); return; } index2 = hash2(hashCode); key2 = keyTable[index2]; if (key2 == null) { keyTable[index2] = evictedKey; valueTable[index2] = evictedValue; if (size++ >= threshold) resize(capacity << 1); return; } index3 = hash3(hashCode); key3 = keyTable[index3]; if (key3 == null) { keyTable[index3] = evictedKey; valueTable[index3] = evictedValue; if (size++ >= threshold) resize(capacity << 1); return; } if (++i == pushIterations) break; insertKey = evictedKey; insertValue = evictedValue; } while (true); putStash(evictedKey, evictedValue); }