public object GetPrimary()
        {
            object primary;

            DependentHandle.nGetPrimary(this._handle, out primary);
            return(primary);
        }
        public DependentHandle(object primary, object secondary)
        {
            IntPtr dependentHandle = (IntPtr)0;

            DependentHandle.nInitialize(primary, secondary, out dependentHandle);
            this._handle = dependentHandle;
        }
        public object GetPrimary()
        {
            object result;

            DependentHandle.nGetPrimary(this._handle, out result);
            return(result);
        }
        private void Resize()
        {
            int  num2;
            int  length = this._buckets.Length;
            bool flag   = false;

            for (num2 = 0; num2 < this._entries.Length; num2++)
            {
                if (this._entries[num2].depHnd.IsAllocated && (this._entries[num2].depHnd.GetPrimary() == null))
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                length = HashHelpers.GetPrime((this._buckets.Length == 0) ? 6 : (this._buckets.Length * 2));
            }
            int num3 = -1;

            int[] numArray = new int[length];
            for (int i = 0; i < length; i++)
            {
                numArray[i] = -1;
            }
            Entry <TKey, TValue>[] entryArray = new Entry <TKey, TValue> [length];
            num2 = 0;
            while (num2 < this._entries.Length)
            {
                DependentHandle depHnd = this._entries[num2].depHnd;
                if (depHnd.IsAllocated && (depHnd.GetPrimary() != null))
                {
                    int index = this._entries[num2].hashCode % length;
                    entryArray[num2].depHnd   = depHnd;
                    entryArray[num2].hashCode = this._entries[num2].hashCode;
                    entryArray[num2].next     = numArray[index];
                    numArray[index]           = num2;
                }
                else
                {
                    this._entries[num2].depHnd.Free();
                    entryArray[num2].depHnd = new DependentHandle();
                    entryArray[num2].next   = num3;
                    num3 = num2;
                }
                num2++;
            }
            while (num2 != entryArray.Length)
            {
                entryArray[num2].depHnd = new DependentHandle();
                entryArray[num2].next   = num3;
                num3 = num2;
                num2++;
            }
            this._buckets  = numArray;
            this._entries  = entryArray;
            this._freeList = num3;
        }
 public void Free()
 {
     if (this._handle != (IntPtr)0)
     {
         IntPtr handle = this._handle;
         this._handle = (IntPtr)0;
         DependentHandle.nFree(handle);
     }
 }
示例#6
0
        private void Resize()
        {
            int  num  = this._buckets.Length;
            bool flag = false;
            int  i;

            for (i = 0; i < this._entries.Length; i++)
            {
                if (this._entries[i].depHnd.IsAllocated && this._entries[i].depHnd.GetPrimary() == null)
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                num = HashHelpers.GetPrime((this._buckets.Length == 0) ? 6 : (this._buckets.Length * 2));
            }
            int num2 = -1;

            int[] array = new int[num];
            for (int j = 0; j < num; j++)
            {
                array[j] = -1;
            }
            ConditionalWeakTable <TKey, TValue> .Entry[] array2 = new ConditionalWeakTable <TKey, TValue> .Entry[num];
            for (i = 0; i < this._entries.Length; i++)
            {
                DependentHandle depHnd = this._entries[i].depHnd;
                if (depHnd.IsAllocated && depHnd.GetPrimary() != null)
                {
                    int num3 = this._entries[i].hashCode % num;
                    array2[i].depHnd   = depHnd;
                    array2[i].hashCode = this._entries[i].hashCode;
                    array2[i].next     = array[num3];
                    array[num3]        = i;
                }
                else
                {
                    this._entries[i].depHnd.Free();
                    array2[i].depHnd = default(DependentHandle);
                    array2[i].next   = num2;
                    num2             = i;
                }
            }
            while (i != array2.Length)
            {
                array2[i].depHnd = default(DependentHandle);
                array2[i].next   = num2;
                num2             = i;
                i++;
            }
            this._buckets  = array;
            this._entries  = array2;
            this._freeList = num2;
        }
        private void Resize()
        {
            int  length = this._buckets.Length;
            bool flag   = false;

            for (int index = 0; index < this._entries.Length; ++index)
            {
                if (this._entries[index].depHnd.IsAllocated && this._entries[index].depHnd.GetPrimary() == null)
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                length = HashHelpers.GetPrime(this._buckets.Length == 0 ? 6 : this._buckets.Length * 2);
            }
            int num = -1;

            int[] numArray = new int[length];
            for (int index = 0; index < length; ++index)
            {
                numArray[index] = -1;
            }
            ConditionalWeakTable <TKey, TValue> .Entry[] entryArray = new ConditionalWeakTable <TKey, TValue> .Entry[length];
            int index1;

            for (index1 = 0; index1 < this._entries.Length; ++index1)
            {
                DependentHandle dependentHandle = this._entries[index1].depHnd;
                if (dependentHandle.IsAllocated && dependentHandle.GetPrimary() != null)
                {
                    int index2 = this._entries[index1].hashCode % length;
                    entryArray[index1].depHnd   = dependentHandle;
                    entryArray[index1].hashCode = this._entries[index1].hashCode;
                    entryArray[index1].next     = numArray[index2];
                    numArray[index2]            = index1;
                }
                else
                {
                    this._entries[index1].depHnd.Free();
                    entryArray[index1].depHnd = new DependentHandle();
                    entryArray[index1].next   = num;
                    num = index1;
                }
            }
            for (; index1 != entryArray.Length; ++index1)
            {
                entryArray[index1].depHnd = new DependentHandle();
                entryArray[index1].next   = num;
                num = index1;
            }
            this._buckets  = numArray;
            this._entries  = entryArray;
            this._freeList = num;
        }
        public void Free()
        {
            if (!(this._handle != (IntPtr)0))
            {
                return;
            }
            IntPtr dependentHandle = this._handle;

            this._handle = (IntPtr)0;
            DependentHandle.nFree(dependentHandle);
        }
示例#9
0
            internal Container Resize(int newSize)
            {
                Debug.Assert(IsPowerOfTwo(newSize));

                // Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
                // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
                int[] newBuckets = new int[newSize];
                for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
                {
                    newBuckets[bucketIndex] = -1;
                }
                Entry[] newEntries      = new Entry[newSize];
                int     newEntriesIndex = 0;

                // Migrate existing entries to the new table.
                for (int entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
                {
                    int             hashCode = _entries[entriesIndex].HashCode;
                    DependentHandle depHnd   = _entries[entriesIndex].depHnd;
                    if (hashCode != -1 && depHnd.IsAllocated)
                    {
                        object primary, secondary;
                        depHnd.GetPrimaryAndSecondary(out primary, out secondary);
                        if (primary != null)
                        {
                            // Entry is used and has not expired. Link it into the appropriate bucket list.
                            newEntries[newEntriesIndex].HashCode = hashCode;
                            newEntries[newEntriesIndex].depHnd   = depHnd;
                            int bucket = hashCode & (newBuckets.Length - 1);
                            newEntries[newEntriesIndex].Next = newBuckets[bucket];
                            newBuckets[bucket] = newEntriesIndex;
                            newEntriesIndex++;
                        }
                        else
                        {
                            // Pretend the item was removed, so that this container's finalizer
                            // will clean up this dependent handle.
                            Volatile.Write(ref _entries[entriesIndex].HashCode, -1);
                        }
                    }
                }

                // Create the new container.  We want to transfer the responsibility of freeing the handles from
                // the old container to the new container, and also ensure that the new container isn't finalized
                // while the old container may still be in use.  As such, we store a reference from the old container
                // to the new one, which will keep the new container alive as long as the old one is.
                var newContainer = new Container(_parent, newBuckets, newEntries, newEntriesIndex);

                _oldKeepAlive = newContainer; // once this is set, the old container's finalizer will not free transferred dependent handles

                GC.KeepAlive(this);           // ensure we don't get finalized while accessing DependentHandles.

                return(newContainer);
            }
示例#10
0
            internal Container Resize(int newSize)
            {
                Debug.Assert(IsPowerOfTwo(newSize));

                // Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
                // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
                int[] newBuckets = new int[newSize];
                for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
                {
                    newBuckets[bucketIndex] = -1;
                }
                Entry[] newEntries      = new Entry[newSize];
                int     newEntriesIndex = 0;

                // Migrate existing entries to the new table.
                for (int entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
                {
                    int             hashCode = _entries[entriesIndex].hashCode;
                    DependentHandle depHnd   = _entries[entriesIndex].depHnd;
                    if (hashCode != -1 && depHnd.IsAllocated && depHnd.GetPrimary() != null)
                    {
                        // Entry is used and has not expired. Link it into the appropriate bucket list.
                        // Note that we have to copy the DependentHandle, since the original copy will be freed
                        // by the Container's finalizer.
                        newEntries[newEntriesIndex].hashCode = hashCode;
                        newEntries[newEntriesIndex].depHnd   = depHnd.AllocateCopy();
                        int bucket = hashCode & (newBuckets.Length - 1);
                        newEntries[newEntriesIndex].next = newBuckets[bucket];
                        newBuckets[bucket] = newEntriesIndex;
                        newEntriesIndex++;
                    }
                }

                GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.

                return(new Container(newBuckets, newEntries, newEntriesIndex));
            }
        private void Resize()
        {
            // Start by assuming we won't resize.
            int newSize = _buckets.Length;

            // If any expired keys exist, we won't resize.
            bool hasExpiredEntries = false;
            int  entriesIndex;

            for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
            {
                if (_entries[entriesIndex].depHnd.IsAllocated && _entries[entriesIndex].depHnd.GetPrimary() == null)
                {
                    hasExpiredEntries = true;
                    break;
                }
            }

            if (!hasExpiredEntries)
            {
                newSize = System.Collections.HashHelpers.GetPrime(_buckets.Length == 0 ? _initialCapacity + 1 : _buckets.Length * 2);
            }


            // Reallocate both buckets and entries and rebuild the bucket and freelists from scratch.
            // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
            int newFreeList = -1;

            int[] newBuckets = new int[newSize];
            for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
            {
                newBuckets[bucketIndex] = -1;
            }
            Entry[] newEntries = new Entry[newSize];

            // Migrate existing entries to the new table.
            for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
            {
                DependentHandle depHnd = _entries[entriesIndex].depHnd;
                if (depHnd.IsAllocated && depHnd.GetPrimary() != null)
                {
                    // Entry is used and has not expired. Link it into the appropriate bucket list.
                    int bucket = _entries[entriesIndex].hashCode % newSize;
                    newEntries[entriesIndex].depHnd   = depHnd;
                    newEntries[entriesIndex].hashCode = _entries[entriesIndex].hashCode;
                    newEntries[entriesIndex].next     = newBuckets[bucket];
                    newBuckets[bucket] = entriesIndex;
                }
                else
                {
                    // Entry has either expired or was on the freelist to begin with. Either way
                    // insert it on the new freelist.
                    _entries[entriesIndex].depHnd.Free();
                    newEntries[entriesIndex].depHnd = new DependentHandle();
                    newEntries[entriesIndex].next   = newFreeList;
                    newFreeList = entriesIndex;
                }
            }

            // Add remaining entries to freelist.
            while (entriesIndex != newEntries.Length)
            {
                newEntries[entriesIndex].depHnd = new DependentHandle();
                newEntries[entriesIndex].next   = newFreeList;
                newFreeList = entriesIndex;
                entriesIndex++;
            }

            _buckets  = newBuckets;
            _entries  = newEntries;
            _freeList = newFreeList;
        }
示例#12
0
            internal Container Resize()
            {
                // Start by assuming we won't resize.
                int newSize = _buckets.Length;

                // If any expired or removed keys exist, we won't resize.
                bool hasExpiredEntries = false;
                int  entriesIndex;

                for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
                {
                    if (_entries[entriesIndex].hashCode == -1)
                    {
                        // the entry was removed
                        hasExpiredEntries = true;
                        break;
                    }

                    if (_entries[entriesIndex].depHnd.IsAllocated && _entries[entriesIndex].depHnd.GetPrimary() == null)
                    {
                        // the entry has expired
                        hasExpiredEntries = true;
                        break;
                    }
                }

                if (!hasExpiredEntries)
                {
                    newSize = System.Collections.HashHelpers.GetPrime(_buckets.Length == 0 ? _initialCapacity + 1 : _buckets.Length * 2);
                }


                // Reallocate both buckets and entries and rebuild the bucket and freelists from scratch.
                // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
                int newFreeList = -1;

                int[] newBuckets = new int[newSize];
                for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
                {
                    newBuckets[bucketIndex] = -1;
                }
                Entry[] newEntries = new Entry[newSize];

                // Migrate existing entries to the new table.
                for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
                {
                    DependentHandle depHnd = _entries[entriesIndex].depHnd;
                    if (_entries[entriesIndex].hashCode != -1 && depHnd.IsAllocated && depHnd.GetPrimary() != null)
                    {
                        // Entry is used and has not expired. Link it into the appropriate bucket list.
                        // Note that we have to copy the DependentHandle, since the original copy will be freed
                        // by the Container's finalizer.
                        int bucket = _entries[entriesIndex].hashCode % newSize;
                        newEntries[entriesIndex].depHnd   = depHnd.AllocateCopy();
                        newEntries[entriesIndex].hashCode = _entries[entriesIndex].hashCode;
                        newEntries[entriesIndex].next     = newBuckets[bucket];
                        newBuckets[bucket] = entriesIndex;
                    }
                    else
                    {
                        // Entry has either expired or was on the freelist to begin with. Either way
                        // insert it on the new freelist.
                        // We do not free the underlying GC handle here, as we may be racing with readers who already saw
                        // the old Container.  The GC handle will be free'd in Container's finalizer.
                        newEntries[entriesIndex].depHnd = new DependentHandle();
                        newEntries[entriesIndex].next   = newFreeList;
                        newFreeList = entriesIndex;
                    }
                }

                // Add remaining entries to freelist.
                while (entriesIndex != newEntries.Length)
                {
                    newEntries[entriesIndex].depHnd = new DependentHandle();
                    newEntries[entriesIndex].next   = newFreeList;
                    newFreeList = entriesIndex;
                    entriesIndex++;
                }

                GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.

                return(new Container()
                {
                    _buckets = newBuckets,
                    _entries = newEntries,
                    _freeList = newFreeList
                });
            }
 public void GetPrimaryAndSecondary(out object primary, out object secondary)
 {
     DependentHandle.nGetPrimaryAndSecondary(this._handle, out primary, out secondary);
 }