コード例 #1
0
 /// <summary>
 /// Capacity specifies the initial size of the StringDictionary. The StringDictionary grows too accomodate more entries as they are added.
 /// </summary>
 /// <param name="capacity"></param>
 public StringDictionary(int capacity)
 {
     _capacity      = (capacity > _minCapacity ? GetNextCapacity(capacity) : _minCapacity);
     _capacityLess1 = _capacity - 1;
     // Minimum capacity of StringDictionary = 1024 entries
     _entries = new StringDictionaryEntry <T> [_capacity];
     // Initialize the space map
     _spaceMap = new BitArray(_capacity);
 }
コード例 #2
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;
                    if (!_spaceMap[(int)(hash & _capacityLess1)])
                    {
                        _entries[hash & _capacityLess1] = new StringDictionaryEntry <T>(hashA, hashB, keyValue);
                        inserted = true;
                        _spaceMap[(int)(hash & (_capacityLess1))] = 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 StringDictionaryEntry <T>(hashA, hashB, keyValue);
                                inserted = true;
                                _spaceMap[(int)(hash & _capacityLess1)] = true;
                                break;
                            }
                        }
                    }
                }
                Count++;
            }
        }
コード例 #3
0
        ///// <summary>
        ///// Determines whether a given key exists in the StringDictionary.
        ///// Complexity O(1)
        ///// </summary>
        ///// <param name="key"></param>
        ///// <returns></returns>
        //public bool Remove(string key)
        //{
        //    //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]);
        //    }

        //    int index;
        //    uint hash;
        //    lock (_syncRoot)
        //    {
        //        for (int i = 0; i < _numHashes; i++)
        //        {
        //            hash = hashA + _primes[i] * hashB;
        //            index = (int)(hash & _capacityLess1);
        //            if (!_spaceMap[index])
        //            {
        //                break;
        //            }
        //            else if (_entries[index].HashA == hashA && _entries[index].HashB == hashB)
        //            {
        //                _entries[index] = null;
        //                _spaceMap[index] = false;
        //                return true;
        //            }
        //        }
        //    }
        //    return false;
        //}

        /// <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;
            StringDictionaryEntry <T>[] newEntries = new StringDictionaryEntry <T> [_capacity];
            BitArray newSpaceMap = new BitArray(_capacity);

            uint hash;

            for (int i = 0; i < _entries.Length; i++)
            {
                if (_spaceMap[i])
                {
                    //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;
                    //        break;
                    //    }
                    //}
                    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;
        }