Esempio n. 1
0
        private void Insert(TKey key, TValue value, bool add)
        {
            if (key == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            }

            if (buckets == null)
            {
                Initialize(0);
            }
            int hashCode     = comparer.GetHashCode(key) & 0x7FFFFFFF;
            int targetBucket = hashCode % buckets.Length;

#if FEATURE_RANDOMIZED_STRING_HASHING
            int collisionCount = 0;
#endif

            for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
            {
                if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
                {
                    if (add)
                    {
                        ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
                    }
                    entries[i].value = value;
                    version++;
                    return;
                }

#if FEATURE_RANDOMIZED_STRING_HASHING
                collisionCount++;
#endif
            }
            int index;
            if (freeCount > 0)
            {
                index    = freeList;
                freeList = entries[index].next;
                freeCount--;
            }
            else
            {
                if (count == entries.Length)
                {
                    Resize();
                    targetBucket = hashCode % buckets.Length;
                }
                index = count;
                count++;
            }

            entries[index].hashCode = hashCode;
            entries[index].next     = buckets[targetBucket];
            entries[index].key      = key;
            entries[index].value    = value;
            buckets[targetBucket]   = index;
            version++;

#if FEATURE_RANDOMIZED_STRING_HASHING
            // In case we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
            // in this case will be EqualityComparer<string>.Default.
            // Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will
            // be using randomized string hashing

            if (collisionCount > HashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default)
            {
                comparer = (IEqualityComparer <TKey>)EqualityComparer <string> .Default;
                Resize(entries.Length, true);
            }
#endif
        }
Esempio n. 2
0
        //-替换 && 添加
        //-查找规则:0.当有备用数组元素时,取备用数组 1.当数组长度已满时,扩容,取第一个 2.当数组长度未满时,取第一个
        private void Insert(TKey key, TValue value, bool add)
        {
            if (key == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            }

            if (buckets == null)
            {
                Initialize(0);
            }
            int hashCode     = comparer.GetHashCode(key) & 0x7FFFFFFF;
            int targetBucket = hashCode % buckets.Length;

#if FEATURE_RANDOMIZED_STRING_HASHING
            int collisionCount = 0;
#endif

            for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
            {
                if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
                {
                    if (add)
                    {
                        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
                    }
                    entries[i].value = value;
                    version++;
                    return;
                }

#if FEATURE_RANDOMIZED_STRING_HASHING
                collisionCount++;
#endif
            }
            int headIndex;
            if (freeCount > 0)
            {
                headIndex = freeList;
                freeList  = entries[headIndex].next;
                freeCount--;
            }
            //- Count = count - freeCount;
            else  //-当前没有多余Count,扩容,取最后一位
            {
                if (count == entries.Length)
                {
                    Resize();
                    targetBucket = hashCode % buckets.Length;
                }
                headIndex = count;
                count++;
            }
//-遍历是按照他的添加顺序来决定的
            entries[headIndex].hashCode = hashCode;
            //-添加链表
            var beforeHandIndex = buckets[targetBucket];
            buckets[targetBucket]    = headIndex;
            entries[headIndex].key   = key;
            entries[headIndex].value = value;
            entries[headIndex].next  = beforeHandIndex;
            //-buckets[targetBucket]永远只存第一个元素,把当前index放在buckets的第一位
            version++;

#if FEATURE_RANDOMIZED_STRING_HASHING
#if FEATURE_CORECLR
            // In case we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
            // in this case will be EqualityComparer<string>.Default.
            // Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will
            // be using randomized string hashing

            if (collisionCount > HashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default)
            {
                comparer = (IEqualityComparer <TKey>)EqualityComparer <string> .Default;
                Resize(entries.Length, true);
            }
#else
            if (collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer))
            {
                comparer = (IEqualityComparer <TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer);
                Resize(entries.Length, true);
            }
#endif // FEATURE_CORECLR
#endif
        }
Esempio n. 3
0
        void ICollection.CopyTo(Array array, int index)
        {
            if (array == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            }

            if (array.Rank != 1)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
            }

            if (array.GetLowerBound(0) != 0)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
            }

            if (index < 0 || index > array.Length)
            {
                ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
            }

            if (array.Length - index < Count)
            {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
            }

            KeyValuePair <TKey, TValue>[] pairs = array as KeyValuePair <TKey, TValue>[];
            if (pairs != null)
            {
                CopyTo(pairs, index);
            }
            else if (array is DictionaryEntry[])
            {
                DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
                Entry[]           entries        = this.entries;
                for (int i = 0; i < count; i++)
                {
                    if (entries[i].hashCode >= 0)
                    {
                        dictEntryArray[index++] = new DictionaryEntry(entries[i].key, entries[i].value);
                    }
                }
            }
            else
            {
                object[] objects = array as object[];
                if (objects == null)
                {
                    ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
                }

                try {
                    int     count   = this.count;
                    Entry[] entries = this.entries;
                    for (int i = 0; i < count; i++)
                    {
                        if (entries[i].hashCode >= 0)
                        {
                            objects[index++] = new KeyValuePair <TKey, TValue>(entries[i].key, entries[i].value);
                        }
                    }
                }
                catch (ArrayTypeMismatchException) {
                    ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
                }
            }
        }
Esempio n. 4
0
        private void Insert(TKey key, TValue value, bool add)
        {
            if (key == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            }

            if (buckets == null)
            {
                Initialize(0);
            }

            if (this.isSimpleKey)
            {
                if (this.simpleBuckets.HasOwnProperty(key))
                {
                    if (add)
                    {
                        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
                    }

                    entries[GetBucket(this.simpleBuckets, key)].value = value;
                    version++;
                    return;
                }

                int simpleIndex;
                if (freeCount > 0)
                {
                    simpleIndex = freeList;
                    freeList    = entries[simpleIndex].next;
                    freeCount--;
                }
                else
                {
                    if (count == entries.Length)
                    {
                        Resize();
                    }
                    simpleIndex = count;
                    count++;
                }

                entries[simpleIndex].hashCode = 1;
                entries[simpleIndex].next     = -1;
                entries[simpleIndex].key      = key;
                entries[simpleIndex].value    = value;

                SetBucket(simpleBuckets, key, simpleIndex);
                version++;

                return;
            }

            int hashCode     = comparer.GetHashCode(key) & 0x7FFFFFFF;
            int targetBucket = hashCode % buckets.Length;

            for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
            {
                if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
                {
                    if (add)
                    {
                        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
                    }
                    entries[i].value = value;
                    version++;
                    return;
                }
            }
            int index;

            if (freeCount > 0)
            {
                index    = freeList;
                freeList = entries[index].next;
                freeCount--;
            }
            else
            {
                if (count == entries.Length)
                {
                    Resize();
                    targetBucket = hashCode % buckets.Length;
                }
                index = count;
                count++;
            }

            entries[index].hashCode = hashCode;
            entries[index].next     = buckets[targetBucket];
            entries[index].key      = key;
            entries[index].value    = value;
            buckets[targetBucket]   = index;
            version++;
        }