internal static GetInstanceDelegate Search(this ImmutableHashTable <Type, GetInstanceDelegate> hashTable, Type key) { var hashCode = key.GetHashCode(); var bucketIndex = hashCode & (hashTable.Divisor - 1); ImmutableHashTree <Type, GetInstanceDelegate> tree = hashTable.Buckets[bucketIndex]; while (tree.Height != 0 && tree.HashCode != hashCode) { tree = hashCode < tree.HashCode ? tree.Left : tree.Right; } if (tree.Height != 0 && ReferenceEquals(tree.Key, key)) { return(tree.Value); } if (tree.Duplicates.Items.Length > 0) { foreach (var keyValue in tree.Duplicates.Items) { if (ReferenceEquals(keyValue.Key, key)) { return(keyValue.Value); } } } return(default(GetInstanceDelegate)); }
private void AddExistingValues(ImmutableHashTable <TKey, TValue> previous) { foreach (ImmutableHashTree <TKey, TValue> bucket in previous.Buckets) { foreach (var keyValue in bucket.InOrder()) { int hashCode = keyValue.Key.GetHashCode(); int bucketIndex = hashCode & (this.Divisor - 1); this.Buckets[bucketIndex] = this.Buckets[bucketIndex].Add(keyValue.Key, keyValue.Value); } } }
/// <summary> /// Initializes a new instance of the <see cref="ImmutableHashTable{TKey,TValue}"/> class. /// </summary> /// <param name="previous">The "previous" hash table that contains already existing values.</param> /// <param name="key">The key to be associated with the value.</param> /// <param name="value">The value to be added to the tree.</param> internal ImmutableHashTable(ImmutableHashTable <TKey, TValue> previous, TKey key, TValue value) { this.Count = previous.Count + 1; if (previous.Count >= previous.Divisor) { this.Divisor = previous.Divisor * 2; this.Buckets = new ImmutableHashTree <TKey, TValue> [this.Divisor]; InitializeBuckets(0, this.Divisor); this.AddExistingValues(previous); } else { this.Divisor = previous.Divisor; this.Buckets = new ImmutableHashTree <TKey, TValue> [this.Divisor]; Array.Copy(previous.Buckets, this.Buckets, previous.Divisor); } var hashCode = key.GetHashCode(); var bucketIndex = hashCode & (this.Divisor - 1); this.Buckets[bucketIndex] = this.Buckets[bucketIndex].Add(key, value); }
/// <summary> /// Adds a new element to the <see cref="ImmutableHashTree{TKey,TValue}"/>. /// </summary> /// <typeparam name="TKey">The type of the key.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="hashTable">The target <see cref="ImmutableHashTable{TKey,TValue}"/>.</param> /// <param name="key">The key to be associated with the value.</param> /// <param name="value">The value to be added to the tree.</param> /// <returns>A new <see cref="ImmutableHashTree{TKey,TValue}"/> that contains the new key/value pair.</returns> public static ImmutableHashTable <TKey, TValue> Add <TKey, TValue>(this ImmutableHashTable <TKey, TValue> hashTable, TKey key, TValue value) { return(new ImmutableHashTable <TKey, TValue>(hashTable, key, value)); }