private void Initialize(int capacity) { int size = MyHashHelpers.GetPrime(capacity); buckets = new int[size]; for (int i = 0; i < buckets.Length; i++) { buckets[i] = -1; } entries = new Entry[size]; freeList = -1; }
[SecurityCritical] // auto-generated_required public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.info); } info.AddValue(VersionName, version); #if FEATURE_RANDOMIZED_STRING_HASHING info.AddValue(ComparerName, MyHashHelpers.GetEqualityComparerForSerialization(comparer), typeof(IEqualityComparer <TKey>)); #else info.AddValue(ComparerName, comparer, typeof(IEqualityComparer <TKey>)); #endif info.AddValue(HashSizeName, buckets == null ? 0 : buckets.Length); //This is the length of the bucket array. if (buckets != null) { KeyValuePair <TKey, TValue>[] array = new KeyValuePair <TKey, TValue> [Count]; CopyTo(array, 0); info.AddValue(KeyValuePairsName, array, typeof(KeyValuePair <TKey, TValue>[])); } }
private void Resize() { Resize(MyHashHelpers.ExpandPrime(count), false); }
private void Insert(TKey key, TValue value, bool add) { if (key == null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); } if (buckets == null) { Initialize(0); } int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF; int targetBucket = hashCode % buckets.Length; #if FEATURE_RANDOMIZED_STRING_HASHING int collisionCount = 0; #endif for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) { if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) { if (add) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate); } entries[i].value = value; version++; return; } #if FEATURE_RANDOMIZED_STRING_HASHING collisionCount++; #endif } 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++; #if FEATURE_RANDOMIZED_STRING_HASHING #if FEATURE_CORECLR // In case we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing // in this case will be EqualityComparer<string>.Default. // Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will // be using randomized string hashing if (collisionCount > MyHashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default) { comparer = (IEqualityComparer <TKey>)EqualityComparer <string> .Default; Resize(entries.Length, true); } #else if (collisionCount > MyHashHelpers.HashCollisionThreshold && MyHashHelpers.IsWellKnownEqualityComparer(comparer)) { comparer = (IEqualityComparer <TKey>)MyHashHelpers.GetRandomizedEqualityComparer(comparer); Resize(entries.Length, true); } #endif // FEATURE_CORECLR #endif }