private void IncreaseCapacity() { int min = this.m_count * 2; if (min < 0) { min = this.m_count; } int prime = HashHelpers.GetPrime(min); if (prime <= this.m_count) { throw new ArgumentException(SR.GetString("Arg_HSCapacityOverflow")); } Slot[] destinationArray = new Slot[prime]; if (this.m_slots != null) { Array.Copy(this.m_slots, 0, destinationArray, 0, this.m_lastIndex); } int[] numArray = new int[prime]; for (int i = 0; i < this.m_lastIndex; i++) { int index = destinationArray[i].hashCode % prime; destinationArray[i].next = numArray[index] - 1; numArray[index] = i + 1; } this.m_slots = destinationArray; this.m_buckets = numArray; }
private void Initialize(int capacity) { int prime = HashHelpers.GetPrime(capacity); this.m_buckets = new int[prime]; this.m_slots = new Slot[prime]; }
public void TrimExcess() { if (this.m_count == 0) { this.m_buckets = null; this.m_slots = null; this.m_version++; } else { int prime = HashHelpers.GetPrime(this.m_count); Slot[] slotArray = new Slot[prime]; int[] numArray = new int[prime]; int index = 0; for (int i = 0; i < this.m_lastIndex; i++) { if (this.m_slots[i].hashCode >= 0) { slotArray[index] = this.m_slots[i]; int num4 = slotArray[index].hashCode % prime; slotArray[index].next = numArray[num4] - 1; numArray[num4] = index + 1; index++; } } this.m_lastIndex = index; this.m_slots = slotArray; this.m_buckets = numArray; this.m_freeList = -1; } }
private void Initialize(int capacity) { int size = HashHelpers.GetPrime(capacity); buckets = new int[size]; for (int i = 0; i < buckets.Length; i++) buckets[i] = -1; entries = new Entry[size]; freeList = -1; }
private void Initialize(int capacity) { int size = HashHelpers.GetPrime(capacity); _buckets = new int[size]; _slots = new Slot[size]; }
public void TrimExcess() { if (_count == 0) { _buckets = null; _slots = null; _version++; } else { int newSize = HashHelpers.GetPrime(_count); Slot[] newSlots = new Slot[newSize]; int[] newBuckets = new int[newSize]; int newIndex = 0; for (int i = 0; i < _lastIndex; i++) { if (_slots[i].hashCode >= 0) { newSlots[newIndex] = _slots[i]; int bucket = newSlots[newIndex].hashCode % newSize; newSlots[newIndex].next = newBuckets[bucket] - 1; newBuckets[bucket] = newIndex + 1; newIndex++; } } _lastIndex = newIndex; _slots = newSlots; _buckets = newBuckets; _freeList = -1; } }
/// <summary> /// Initializes buckets and slots arrays. Uses suggested capacity by finding next prime /// greater than or equal to capacity. /// </summary> /// <param name="capacity"></param> private void Initialize(int capacity) { Debug.Assert(m_buckets == null, "Initialize was called but m_buckets was non-null"); int size = HashHelpers.GetPrime(capacity); m_buckets = new int[size]; m_slots = new Slot[size]; }
private void Initialize(int capacity) { int prime = HashHelpers.GetPrime(capacity); this.buckets = new int[prime]; for (int i = 0; i < this.buckets.Length; i++) { this.buckets[i] = -1; } this.entries = new Entry <TKey, TValue> [prime]; this.freeList = -1; }
private int Initialize(int capacity) { var size = HashHelpers.GetPrime(capacity); var buckets = new SegmentedList <int>(defaultSegmentSize, size); var entries = new SegmentedList <Entry>(defaultSegmentSize, size); // Assign member variables after both arrays allocated to guard against corruption from OOM if second fails _freeList = -1; _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)buckets.Capacity); _buckets = buckets; _entries = entries; return(size); }
/// <summary> /// Sets the capacity of this list to the size of the list (rounded up to nearest prime), /// unless count is 0, in which case we release references. /// /// This method can be used to minimize a list's memory overhead once it is known that no /// new elements will be added to the list. To completely clear a list and release all /// memory referenced by the list, execute the following statements: /// /// list.Clear(); /// list.TrimExcess(); /// </summary> public void TrimExcess() { Debug.Assert(m_count >= 0, "m_count is negative"); if (m_count == 0) { // if count is zero, clear references m_buckets = null; m_slots = null; m_version++; } else { Debug.Assert(m_buckets != null, "m_buckets was null but m_count > 0"); // similar to IncreaseCapacity but moves down elements in case add/remove/etc // caused fragmentation int newSize = HashHelpers.GetPrime(m_count); Slot[] newSlots = new Slot[newSize]; int[] newBuckets = new int[newSize]; // move down slots and rehash at the same time. newIndex keeps track of current // position in newSlots array int newIndex = 0; for (int i = 0; i < m_lastIndex; i++) { if (m_slots[i].hashCode >= 0) { newSlots[newIndex] = m_slots[i]; // rehash int bucket = newSlots[newIndex].hashCode % newSize; newSlots[newIndex].next = newBuckets[bucket] - 1; newBuckets[bucket] = newIndex + 1; newIndex++; } } Debug.Assert(newSlots.Length <= m_slots.Length, "capacity increased after TrimExcess"); m_lastIndex = newIndex; m_slots = newSlots; m_buckets = newBuckets; m_freeList = -1; } }
private void Resize() { int prime = HashHelpers.GetPrime(this.count * 2); int[] numArray = new int[prime]; for (int i = 0; i < numArray.Length; i++) { numArray[i] = -1; } Entry <TKey, TValue>[] destinationArray = new Entry <TKey, TValue> [prime]; Array.Copy(this.entries, 0, destinationArray, 0, this.count); for (int j = 0; j < this.count; j++) { int index = destinationArray[j].hashCode % prime; destinationArray[j].next = numArray[index]; numArray[index] = j; } this.buckets = numArray; this.entries = destinationArray; }
private void Resize() { int newSize = HashHelpers.GetPrime(count * 2); int[] newBuckets = new int[newSize]; for (int i = 0; i < newBuckets.Length; i++) { newBuckets[i] = -1; } Entry[] newEntries = new Entry[newSize]; Array.Copy(entries, 0, newEntries, 0, count); for (int i = 0; i < count; i++) { int bucket = newEntries[i].hashCode % newSize; newEntries[i].next = newBuckets[bucket]; newBuckets[bucket] = i; } buckets = newBuckets; entries = newEntries; }
/// <summary> /// Expand to new capacity. New capacity is next prime greater than or equal to suggested /// size. This is called when the underlying array is filled. This performs no /// defragmentation, allowing faster execution; note that this is reasonable since /// AddIfNotPresent attempts to insert new elements in re-opened spots. /// </summary> /// <param name="sizeSuggestion"></param> private void IncreaseCapacity() { Debug.Assert(m_buckets != null, "IncreaseCapacity called on a set with no elements"); // Handle overflow conditions. Try to expand capacity by GrowthFactor. If that causes // overflow, use size suggestion of m_count and see if HashHelpers returns a value // greater than that. If not, capacity can't be increased so throw capacity overflow // exception. int sizeSuggestion = unchecked (m_count * GrowthFactor); if (sizeSuggestion < 0) { sizeSuggestion = m_count; } int newSize = HashHelpers.GetPrime(sizeSuggestion); if (newSize <= m_count) { throw new ArgumentException(SR.GetString(SR.Arg_HSCapacityOverflow)); } // Able to increase capacity; copy elements to larger array and rehash Slot[] newSlots = new Slot[newSize]; if (m_slots != null) { Array.Copy(m_slots, 0, newSlots, 0, m_lastIndex); } int[] newBuckets = new int[newSize]; for (int i = 0; i < m_lastIndex; i++) { int bucket = newSlots[i].hashCode % newSize; newSlots[i].next = newBuckets[bucket] - 1; newBuckets[bucket] = i + 1; } m_slots = newSlots; m_buckets = newBuckets; }