예제 #1
0
        /// <summary>
        /// Initializes hashtable with given equality comparer of T and capacity equal to smallest prime number bigger than provided value.
        /// </summary>
        public HashTable(int capacity, EqualityComparer <T> equalityComparer)
        {
            if (equalityComparer == null)
            {
                throw new ArgumentNullException("Comparer is null");
            }
            this.equalityComparer = equalityComparer;
            if (capacity < 0)
            {
                throw new ArgumentException("Capacity can't be negative");
            }

            // set buckets capacity to next smallest prime
            if (capacity < 17)
            {
                capacity = 17;
            }
            else
            {
                ulong cap = NumericAlgorithms.FindNextPrime((ulong)capacity);
                capacity = cap > int.MaxValue ? int.MaxValue : (int)cap;        //int.MaxValue is prime
            }
            bucketsCapacity = capacity;
            buckets         = new LinkedList <T> [bucketsCapacity];
        }
예제 #2
0
        /// <summary>
        /// Initializes hashtable with given equality comparer and capacity equal to smallest prime number bigger than collection.count
        /// </summary>
        public HashTable(IEnumerable <T> collection, EqualityComparer <T> equalityComparer)
        {
            if (equalityComparer == null)
            {
                throw new ArgumentNullException("Comparer is null");
            }
            this.equalityComparer = equalityComparer;

            // set buckets capacity to next smallest prime
            if (collection == null)
            {
                throw new ArgumentNullException("Collection is null");
            }
            if (collection is IList <T> )
            {
                bucketsCapacity = (collection as IList <T>).Count;
            }
            else
            {
                int cap = 0;
                foreach (var item in collection)
                {
                    cap++;
                }
                bucketsCapacity = cap;
            }
            if (bucketsCapacity < 17)
            {
                bucketsCapacity = 17;
            }
            else
            {
                ulong cap = NumericAlgorithms.FindNextPrime((ulong)bucketsCapacity);
                bucketsCapacity = cap > int.MaxValue ? int.MaxValue : (int)cap;        //int.MaxValue is prime
            }
            buckets = new LinkedList <T> [bucketsCapacity];

            // add collection elements to hashtable
            foreach (var item in collection)
            {
                this.Add(item);
            }
        }
예제 #3
0
        /// <summary>
        /// Adds new item to hashtable. Might cause a reallocation.
        /// </summary>
        public void Add(T item)
        {
            int hashCode    = equalityComparer.GetHashCode(item);
            int bucketIndex = hashCode % bucketsCapacity;

            if (buckets[bucketIndex] == null)
            {
                buckets[bucketIndex] = new LinkedList <T>();
                bucketsCount++;
            }
            buckets[bucketIndex].Add(item);
            elementsCount++;

            //-------------------------- reallocate the buckets collection if required
            // get new bucket capacity if required
            if (LoadFactor <= MaxLoadFactor)
            {
                return;
            }
            ulong newBucketsCapacity = 17;

            if (bucketsCapacity < int.MaxValue / 2)
            {
                newBucketsCapacity = (ulong)bucketsCapacity * 2;
                newBucketsCapacity = NumericAlgorithms.FindNextPrime((ulong)newBucketsCapacity);
            }
            else
            {
                newBucketsCapacity = int.MaxValue;  //its prime
            }
            // for each value in hash table get new index in new reallocated array, copy that value and count new buckets
            var newBuckets      = new LinkedList <T> [newBucketsCapacity];
            int newBucketsCount = 0;

            for (int i = 0; i < buckets.Length; i++)
            {
                if (buckets[i] != null)
                {
                    var list = buckets[i];
                    if (list.Count != 0)
                    {
                        foreach (T value in list)
                        {
                            hashCode = equalityComparer.GetHashCode(value);
                            int newBucketIndex = hashCode % (int)newBucketsCapacity;
                            if (newBuckets[newBucketIndex] == null)
                            {
                                newBuckets[newBucketIndex] = new LinkedList <T>();
                                newBucketsCount++;
                            }
                            newBuckets[newBucketIndex].Add(value);
                        }
                    }
                }
            }

            // copy new values
            buckets         = newBuckets;
            bucketsCapacity = (int)newBucketsCapacity;
            bucketsCount    = newBucketsCount;
        }