/** * Get the value of a counter associated with a key or {@link #initialValue()} if not found. * * @param key lookup key * @return counter value associated with key or {@link #initialValue()} if not found. */ public long get(final long key) { final long[] entries = this.entries; final long initialValue = this.initialValue; @DoNotSub final int mask = entries.length - 1; @DoNotSub int index = Hashing.evenHash(key, mask); long value = initialValue; while (entries[index + 1] != initialValue) { if (entries[index] == key) { value = entries[index + 1]; break; } index = next(index, mask); } return value; }
index = next(index, mask);
/** * Remove a counter value for a given key. * * @param key to be removed * @return old value for key */ public long remove(final long key) { final long[] entries = this.entries; final long initialValue = this.initialValue; @DoNotSub final int mask = entries.length - 1; @DoNotSub int keyIndex = Hashing.evenHash(key, mask); long oldValue = initialValue; while (entries[keyIndex + 1] != initialValue) { if (entries[keyIndex] == key) { @DoNotSub final int valueIndex = keyIndex + 1; oldValue = entries[keyIndex + 1]; entries[keyIndex + 1] = initialValue; size--; compactChain(keyIndex); break; } keyIndex = next(keyIndex, mask); } return oldValue; }
@SuppressWarnings("FinalParameters") private void compactChain(@DoNotSub int deleteKeyIndex) { final long[] entries = this.entries; final long initialValue = this.initialValue; @DoNotSub final int mask = entries.length - 1; @DoNotSub int index = deleteKeyIndex; while (true) { index = next(index, mask); if (entries[index + 1] == initialValue) { break; } @DoNotSub final int hash = Hashing.evenHash(entries[index], mask); if ((index < hash && (hash <= deleteKeyIndex || deleteKeyIndex <= index)) || (hash <= deleteKeyIndex && deleteKeyIndex <= index)) { entries[deleteKeyIndex] = entries[index]; entries[deleteKeyIndex + 1] = entries[index + 1]; entries[index + 1] = initialValue; deleteKeyIndex = index; } } }
index = next(index, mask);
private void rehash(@DoNotSub final int newCapacity) { final long[] oldEntries = entries; final long initialValue = this.initialValue; @DoNotSub final int length = entries.length; capacity(newCapacity); final long[] newEntries = entries; @DoNotSub final int mask = entries.length - 1; for (@DoNotSub int i = 0; i < length; i += 2) { final long value = oldEntries[i + 1]; if (value != initialValue) { final long key = oldEntries[i]; @DoNotSub int index = Hashing.evenHash(key, mask); while (entries[index + 1] != initialValue) { index = next(index, mask); } newEntries[index] = key; newEntries[index + 1] = value; } } } }