Пример #1
0
        public Hashtable(int capacity, float loadFactor, IHashCodeProvider hcp, IComparer comparer)
        {
            if (capacity < 0)
            {
                throw new ArgumentOutOfRangeException("capacity", "negative capacity");
            }

            if (loadFactor < 0.1f || loadFactor > 1.0f || Single.IsNaN(loadFactor))
            {
                throw new ArgumentOutOfRangeException("loadFactor", "load factor");
            }

            if (capacity == 0)
            {
                ++capacity;
            }
            this.loadFactor = 0.75f * loadFactor;
            double tableSize = capacity / this.loadFactor;

            if (tableSize > Int32.MaxValue)
            {
                throw new ArgumentException("Size is too big");
            }

            int size = (int)tableSize;

            size = HashPrimeNumbers.ToPrime(size);
            this.SetTable(new Slot [size], new int [size]);

            this.hcp      = hcp;
            this.comparer = comparer;

            this.inUse             = 0;
            this.modificationCount = 0;
        }
Пример #2
0
        private void Rehash()
        {
            int oldSize = this.table.Length;

            // From the SDK docs:
            //   Hashtable is automatically increased
            //   to the smallest prime number that is larger
            //   than twice the current number of Hashtable buckets
            uint newSize = (uint)HashPrimeNumbers.ToPrime((oldSize << 1) | 1);


            Slot [] newTable  = new Slot [newSize];
            Slot [] table     = this.table;
            int []  newHashes = new int [newSize];
            int []  hashes    = this.hashes;

            for (int i = 0; i < oldSize; i++)
            {
                Slot s = table [i];
                if (s.key != null)
                {
                    int  h    = hashes [i] & Int32.MaxValue;
                    uint spot = (uint)h;
                    uint step = ((uint)(h >> 5) + 1) % (newSize - 1) + 1;
                    for (uint j = spot % newSize;; spot += step, j = spot % newSize)
                    {
                        // No check for KeyMarker.Removed here,
                        // because the table is just allocated.
                        if (newTable [j].key == null)
                        {
                            newTable [j].key   = s.key;
                            newTable [j].value = s.value;
                            newHashes [j]     |= h;
                            break;
                        }
                        else
                        {
                            newHashes [j] |= CHAIN_MARKER;
                        }
                    }
                }
            }

            ++this.modificationCount;

            this.SetTable(newTable, newHashes);
        }
Пример #3
0
        public virtual void OnDeserialization(object sender)
        {
            if (serializationInfo == null)
            {
                return;
            }

            loadFactor        = (float)serializationInfo.GetValue("LoadFactor", typeof(float));
            modificationCount = (int)serializationInfo.GetValue("Version", typeof(int));
            try {
                equalityComparer = (IEqualityComparer)serializationInfo.GetValue("KeyComparer", typeof(object));
            } catch {
                // If not found, try to get "Comparer"
            }

            if (equalityComparer == null)
            {
                comparerRef = (IComparer)serializationInfo.GetValue("Comparer", typeof(object));
            }
            try {
                hcpRef = (IHashCodeProvider)serializationInfo.GetValue("HashCodeProvider", typeof(object));
            } catch {}             // Missing value => null
            int size = (int)serializationInfo.GetValue("HashSize", typeof(int));

            Object [] keys   = (Object [])serializationInfo.GetValue("Keys", typeof(Object []));
            Object [] values = (Object [])serializationInfo.GetValue("Values", typeof(Object []));

            if (keys.Length != values.Length)
            {
                throw new SerializationException("Keys and values of uneven size");
            }

            size = HashPrimeNumbers.ToPrime(size);
            this.SetTable(new Slot [size], new int [size]);

            for (int i = 0; i < keys.Length; i++)
            {
                Add(keys[i], values[i]);
            }

            AdjustThreshold();

            serializationInfo = null;
        }