@Override public boolean remove(final Key key) { if (key == null) throw new IllegalArgumentException("key cannot be null"); if (buckets != null) { int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; int bucket = hashCode % buckets.length; int last = -1; for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next) { if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) { if (last < 0) buckets[bucket] = entries[i].next; else entries[last].next = entries[i].next; entries[i].hashCode = -1; entries[i].next = freeList; entries[i].key = null; entries[i].value = null; freeList = i; freeCount++; version++; return true; } } } return false; }
private int findEntry(Key key) { if (key == null) throw new IllegalArgumentException("key cannot be null"); if (buckets != null) { int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; for (int i = buckets[hashCode % buckets.length]; i >= 0; i = entries[i].next) { if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i; } } return -1; }
private void insert(Key key, Value value, boolean add) { if (key == null) throw new IllegalArgumentException("key cannot be null"); if (buckets == null) initialize(0); int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; int targetBucket = hashCode % buckets.length; for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) { if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) { if (add) throw new IllegalArgumentException("Attempted to add items with duplicate keys"); entries[i].value = value; version++; return; } } int index; if (freeCount > 0) { index = freeList; freeList = entries[index].next; freeCount--; } else { if (count == entries.length) { Resize(); targetBucket = hashCode % buckets.length; } index = count; count++; } entries[index].hashCode = hashCode; entries[index].next = buckets[targetBucket]; entries[index].key = key; entries[index].value = value; buckets[targetBucket] = index; version++; }
private void Resize(int newSize, boolean forceNewHashCodes) { // Contract.Assert(newSize >= entries.Length); int[] newBuckets = new int[newSize]; for (int i = 0; i < newBuckets.length; i++) newBuckets[i] = -1; Entry<Key, Value>[] newEntries = new Entry[newSize]; copy(entries, 0, newEntries, 0, count); setNullsToDefault(newEntries); if (forceNewHashCodes) { for (int i = 0; i < count; i++) { if (newEntries[i].hashCode != -1) { newEntries[i].hashCode = (comparer.GetHashCode(newEntries[i].key) & 0x7FFFFFFF); } } } for (int i = 0; i < count; i++) { if (newEntries[i].hashCode >= 0) { int bucket = newEntries[i].hashCode % newSize; newEntries[i].next = newBuckets[bucket]; newBuckets[bucket] = i; } } buckets = newBuckets; entries = newEntries; }