void Resize() { int newSize = HashPrimeNumbers.ToPrime((table.Length << 1) | 1); // allocate new hash table and link slots array var newTable = new int [newSize]; var newLinks = new Link [newSize]; for (int i = 0; i < table.Length; i++) { int current = table [i] - 1; while (current != NO_SLOT) { int hashCode = newLinks [current].HashCode = GetItemHashCode(slots [current]); int index = (hashCode & int.MaxValue) % newSize; newLinks [current].Next = newTable [index] - 1; newTable [index] = current + 1; current = links [current].Next; } } table = newTable; links = newLinks; // allocate new data slots, copy data var newSlots = new T [newSize]; Array.Copy(slots, 0, newSlots, 0, touched); slots = newSlots; threshold = (int)(newSize * DEFAULT_LOAD_FACTOR); }
private void Resize() { int num = HashPrimeNumbers.ToPrime((this.table.Length << 1) | 1); int[] numArray = new int[num]; Link[] linkArray = new Link[num]; for (int i = 0; i < this.table.Length; i++) { for (int j = this.table[i] - 1; j != -1; j = this.linkSlots[j].Next) { int num4 = linkArray[j].HashCode = this.hcp.GetHashCode(this.keySlots[j]) | -2147483648; int index = (num4 & 0x7fffffff) % num; linkArray[j].Next = numArray[index] - 1; numArray[index] = j + 1; } } this.table = numArray; this.linkSlots = linkArray; TKey[] destinationArray = new TKey[num]; TValue[] localArray2 = new TValue[num]; Array.Copy(this.keySlots, 0, destinationArray, 0, this.touchedSlots); Array.Copy(this.valueSlots, 0, localArray2, 0, this.touchedSlots); this.keySlots = destinationArray; this.valueSlots = localArray2; this.threshold = (int)(num * 0.9f); }
/*LOCKING: _lock must be held*/ void Rehash() { uint newSize = (uint)HashPrimeNumbers.ToPrime((data.Length << 1) | 1); //Console.WriteLine ("--- resizing from {0} to {1}", data.Length, newSize); Ephemeron[] tmp = new Ephemeron [newSize]; GC.register_ephemeron_array(tmp); size = 0; for (int i = 0; i < data.Length; ++i) { object key = data[i].key; object value = data[i].value; if (key == null || key == GC.EPHEMERON_TOMBSTONE) { continue; } int len = tmp.Length; int idx, initial_idx; int free_slot = -1; idx = initial_idx = (RuntimeHelpers.GetHashCode(key) & int.MaxValue) % len; do { object k = tmp [idx].key; //keys might be GC'd during Rehash if (k == null || k == GC.EPHEMERON_TOMBSTONE) { free_slot = idx; break; } if (++idx == len) //Wrap around { idx = 0; } } while (idx != initial_idx); tmp [free_slot].key = key; tmp [free_slot].value = value; ++size; } data = tmp; }
private void Resize() { // From the SDK docs: // Hashtable is automatically increased // to the smallest prime number that is larger // than twice the current number of Hashtable buckets int newSize = HashPrimeNumbers.ToPrime((table.Length << 1) | 1); // allocate new hash table and link slots array var newTable = new int[newSize]; var newLinkSlots = new Link[newSize]; for (int i = 0; i < table.Length; i++) { int cur = table[i] - 1; while (cur != NO_SLOT) { int hashCode = newLinkSlots[cur].HashCode = hcp.GetHashCode(keySlots[cur]) | HASH_FLAG; int index = (hashCode & int.MaxValue) % newSize; newLinkSlots[cur].Next = newTable[index] - 1; newTable[index] = cur + 1; cur = linkSlots[cur].Next; } } table = newTable; linkSlots = newLinkSlots; // allocate new data slots, copy data var newKeySlots = new TKey[newSize]; var newValueSlots = new TValue[newSize]; Array.Copy(keySlots, 0, newKeySlots, 0, touchedSlots); Array.Copy(valueSlots, 0, newValueSlots, 0, touchedSlots); keySlots = newKeySlots; valueSlots = newValueSlots; threshold = (int)(newSize * DEFAULT_LOAD_FACTOR); }