Adding TrimExcess APIs for Dictionary class
authorMaryam Ariyan <maryam.ariyan@microsoft.com>
Wed, 31 Jan 2018 23:49:03 +0000 (18:49 -0500)
committerMaryam Ariyan <maryam.ariyan@microsoft.com>
Thu, 1 Feb 2018 04:34:09 +0000 (23:34 -0500)
src/mscorlib/shared/System/Collections/Generic/Dictionary.cs

index 24eaa0d..541a0b2 100644 (file)
@@ -778,6 +778,61 @@ namespace System.Collections.Generic
             return newSize;
         }
 
+        /// <summary>
+        /// Sets the capacity of this dictionary to what it would be if it had been originally initialized with all its entries
+        /// 
+        /// This method can be used to minimize the memory overhead 
+        /// once it is known that no new elements will be added. 
+        /// 
+        /// To allocate minimum size storage array, execute the following statements:
+        /// 
+        /// dictionary.Clear();
+        /// dictionary.TrimExcess();
+        /// </summary>
+        public void TrimExcess()
+        {
+            TrimExcess(Count);
+        }
+
+        /// <summary>
+        /// Sets the capacity of this dictionary to hold up 'capacity' entries without any further expansion of its backing storage
+        /// 
+        /// This method can be used to minimize the memory overhead 
+        /// once it is known that no new elements will be added. 
+        /// </summary>
+        public void TrimExcess(int capacity)
+        {
+            if (capacity < Count)
+                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity);
+            int newSize = HashHelpers.GetPrime(capacity);
+
+            Entry[] oldEntries = _entries;
+            int currentCapacity = oldEntries == null ? 0 : oldEntries.Length;
+            if (newSize >= currentCapacity)
+                return;
+
+            int oldCount = _count;
+            Initialize(newSize);
+            Entry[] entries = _entries;
+            int[] buckets = _buckets;
+            int count = 0;
+            for (int i = 0; i < oldCount; i++)
+            {
+                int hashCode = oldEntries[i].hashCode;
+                if (hashCode >= 0)
+                {
+                    ref Entry entry = ref entries[count];
+                    entry = oldEntries[i];
+                    int bucket = hashCode % newSize;
+                    entry.next = buckets[bucket];
+                    buckets[bucket] = count;
+                    count++;
+                }
+            }
+            _count = count;
+            _freeCount = 0;
+        }
+
         bool ICollection.IsSynchronized
         {
             get { return false; }