Beispiel #1
0
        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));
        }
Beispiel #2
0
 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);
         }
     }
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
 /// <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));
 }