Example #1
0
 public StringDictionaryWithKey(StringDictionaryWithKey <T> copyDictionary)
 {
     _capacity      = copyDictionary._capacity;
     _capacityLess1 = copyDictionary._capacityLess1;
     _entries       = new StringDictionaryEntryWithKey <T> [_capacity];
     //copyDictionary._entries.CopyTo(_entries, 0);
     _spaceMap = new BitArray(copyDictionary._spaceMap);
     Count     = copyDictionary.Count;
 }
Example #2
0
 public StringDictionaryWithKey() // : this(0)
 {
     _capacity      = 8;          // (capacity > _minCapacity ? GetNextCapacity(capacity) : _minCapacity);
     _capacityLess1 = _capacity - 1;
     // Minimum capacity of StringDictionary = 1024 entries
     _entries = new StringDictionaryEntryWithKey <T> [_capacity];
     // Initialize the space map
     _spaceMap = new BitArray(_capacity);
 }
Example #3
0
        /// <summary>
        /// This methods adds a given Key value pair to the StringDictionary. Keys need to be unique. Values need not be unique.
        /// Complexity Average Case: O(log((n + 1/)n)), Worst Case: O(n)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="keyValue"></param>
        public void Add(string key, T keyValue)
        {
            //GetHashCodes(key, out hashA, out hashB);
            uint hashA = 0, hashB = 0;

            for (int i = 0; i < key.Length; i++)
            {
                hashA = ((hashA << 5) + hashA ^ (uint)key[i]);
                hashB = ((hashB << 6) + (hashB << 16) - hashB + (uint)key[i]);
            }

            uint hash;
            bool inserted = false;

            lock (_syncRoot)
            {
                for (int i = 0; i < _numHashes; i++)
                {
                    hash = hashA + _primes[i] * hashB;
                    int index = (int)(hash & _capacityLess1);
                    if (!_spaceMap[index])
                    {
                        _entries[index]  = new StringDictionaryEntryWithKey <T>(hashA, hashB, keyValue, key);
                        inserted         = true;
                        _spaceMap[index] = true;
                        break;
                    }
                }
                if (!inserted)
                {
                    while (!inserted)
                    {
                        Resize();
                        for (int i = 0; i < _numHashes; i++)
                        {
                            hash = hashA + _primes[i] * hashB;
                            if (!_spaceMap[(int)(hash & _capacityLess1)])
                            {
                                _entries[hash & _capacityLess1] = new StringDictionaryEntryWithKey <T>(hashA, hashB, keyValue, key);
                                inserted = true;
                                _spaceMap[(int)(hash & _capacityLess1)] = true;
                                break;
                            }
                        }
                    }
                }
                Count++;
            }
        }
Example #4
0
        /// <summary>
        /// The number of hashes to generate for insertions / lookups in the StringDictionary.
        /// The default value is 31. Possible values range from 5 to 277 inclusive. A lower value leads to greater performance at the cost of a low load factor.
        /// A higher value leads to lesser performance but higher load factor.
        /// </summary>
        //public int NumHashes
        //{
        //    get { return _numHashes; }
        //    set { _numHashes = ((value < 16) && (value > 278) ? value : 31); }
        //}
        // Indexer
        //public T this[string key]
        //{
        //    get
        //    {
        //        //int index;
        //        //if ((index = ContainsKeyInternal(key)) >= 0)
        //        //    return _entries[index].Value;
        //        //else
        //        //    return default(T);
        //        return this.GetContainsKey(key);
        //    }
        //    //set
        //    //{
        //    //    int index;
        //    //    if ((index = ContainsKeyInternal(key)) >= 0)
        //    //        _entries[index].Value = value;
        //    //    else
        //    //        throw new KeyNotFoundException("Key not found. Key: " + key);
        //    //}
        //}
        #endregion

        #region Utility Functions


        /// <summary>
        ///// The internal method used by ContainsKey(string) method.
        ///// </summary>
        ///// <param name="key"></param>
        ///// <returns></returns>
        //private int ContainsKeyInternal(string key)
        //{
        //    uint hashA, hashB;
        //    uint hash;
        //    GetHashCodes(key, out hashA, out hashB);
        //    for (int i = 0; i < _numHashes; i++)
        //    {
        //        hash = hashA + _primes[i] * hashB;
        //        if (!_spaceMap[(int)(hash & _capacityLess1)])
        //            break;
        //        else if (_entries[hash & _capacityLess1].HashA == hashA && _entries[hash & _capacityLess1].HashB == hashB)
        //            return (int)(hash & _capacityLess1);
        //    }
        //    return -1;
        //}

        /// <summary>
        /// The internal method called to resize the _entries array.
        /// Complexity O(n)
        /// </summary>
        private void Resize()
        {
start:
            _capacity      = _capacity << 1;
            _capacityLess1 = _capacity - 1;
            StringDictionaryEntryWithKey <T>[] newEntries = new StringDictionaryEntryWithKey <T> [_capacity];
            BitArray newSpaceMap = new BitArray(_capacity);

            uint hash;

            for (int i = 0; i < _entries.Length; i++)
            {
                if (_spaceMap[i])
                {
                    bool rehashed = false;
                    for (int j = 0; j < _numHashes; j++)
                    {
                        hash = _entries[i].HashA + _primes[j] * _entries[i].HashB;
                        if (!newSpaceMap[(int)(hash & _capacityLess1)])
                        {
                            newEntries[hash & _capacityLess1]         = _entries[i];
                            newSpaceMap[(int)(hash & _capacityLess1)] = true;
                            rehashed = true;
                            break;
                        }
                    }

                    if (!rehashed)
                    {
                        //Debug.Assert(false, "rehash goto accured.");
                        goto start;
                    }
                }
            }

            _entries  = newEntries;
            _spaceMap = newSpaceMap;
        }