< Summary

Class:GDX.Collections.Generic.StringKeyDictionary[TValue]
Assembly:GDX
File(s):D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/Collections/Generic/StringKeyDictionary.cs
Covered lines:317
Uncovered lines:82
Coverable lines:399
Total lines:683
Line coverage:79.4% (317 of 399)
Covered branches:0
Total branches:0
Covered methods:16
Total methods:19
Method coverage:84.2% (16 of 19)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
StringKeyDictionary(...)0%330100%
AddWithExpandCheck(...)0%33095%
AddWithUniqueCheck(...)0%4.014092.31%
AddSafe(...)0%5.025090%
AddUnchecked(...)0%110100%
ContainsKey(...)0%4.254075%
ExpandWhenFull()0%440100%
Reserve(...)0%6.146084.21%
IndexOf(...)0%44093.75%
TryModifyValue(...)0%20400%
TryRemove(...)0%66097.5%
TryRemoveNoValueClear(...)0%42600%
TryGetValue(...)0%4.024088.89%
MoveNext(...)0%440100%
MoveNext(...)0%330100%
MoveNext(...)0%12300%
Clear()0%330100%

File(s)

D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/Collections/Generic/StringKeyDictionary.cs

#LineLine coverage
 1using System;
 2
 3namespace GDX.Collections.Generic
 4{
 5    /// <summary>
 6    ///     An optimized <see cref="System.Collections.Generic.Dictionary{T,T}" />-like data structure with a
 7    ///     <see cref="string"/> key requirement.
 8    /// </summary>
 9    [Serializable]
 10    public struct StringKeyDictionary<TValue>
 11    {
 12        public int[] Buckets;
 13        public StringKeyEntry<TValue>[] Entries;
 14        public int FreeListHead;
 15        public int Count;
 16
 17        /// <summary>
 18        /// Initializes the dictionary with at least <paramref name="minCapacity"/> capacity.
 19        /// </summary>
 20        /// <param name="minCapacity">The minimal initial capacity to reserve.</param>
 21        public StringKeyDictionary(int minCapacity)
 2922        {
 2923            int primeCapacity = DictionaryPrimes.GetPrime(minCapacity);
 24
 2925            Buckets = new int[primeCapacity];
 115226            for (int i = 0; i < primeCapacity; i++)
 54727            {
 54728                Buckets[i] = -1;
 54729            }
 30
 2931            Entries = new StringKeyEntry<TValue>[primeCapacity];
 32
 115233            for (int i = 0; i < primeCapacity; i++)
 54734            {
 54735                Entries[i].Next = (1 << 31) | (i + 1);
 54736            }
 37
 2938            Count = 0;
 2939            FreeListHead = 0;
 2940        }
 41
 42        /// <summary>
 43        /// Adds the key value pair to the dictionary, expanding if necessary but not checking for duplicate entries.
 44        /// </summary>
 45        /// <param name="key">The key to add.</param>
 46        /// <param name="value">The value to add.</param>
 47        public void AddWithExpandCheck(string key, TValue value)
 3748        {
 3749            if (key == null) throw new ArgumentNullException();
 50
 3751            int freeIndex = FreeListHead;
 52
 3753            if (freeIndex >= Buckets.Length)
 254            {
 255                ExpandWhenFull();
 256            }
 57
 3758            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 3759            int hashIndex = hashCode % Buckets.Length;
 3760            int indexAtBucket = Buckets[hashIndex];
 3761            ref StringKeyEntry<TValue> entry = ref Entries[freeIndex];
 62
 3763            FreeListHead = entry.Next & 0x7FFFFFFF;
 3764            entry.Next = indexAtBucket;
 3765            entry.Key = key;
 3766            entry.Value = value;
 3767            entry.HashCode = hashCode;
 3768            Buckets[hashIndex] = freeIndex;
 69
 3770            ++Count;
 3771        }
 72
 73        /// <summary>
 74        /// Adds the key value pair to the dictionary, checking for duplicates but not expanding if necessary.
 75        /// </summary>
 76        /// <param name="key">The key to add.</param>
 77        /// <param name="value">The value to add.</param>
 78        /// <returns>True if the entry was successfully created.</returns>
 79        public bool AddWithUniqueCheck(string key, TValue value)
 380        {
 381            if (key == null) throw new ArgumentNullException();
 82
 383            int freeIndex = FreeListHead;
 384            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 385            int hashIndex = hashCode % Buckets.Length;
 386            int indexAtBucket = Buckets[hashIndex];
 87
 388            int nextKeyIndex = indexAtBucket;
 89
 390            while (nextKeyIndex > -1)
 191            {
 192                ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 193                nextKeyIndex = currEntry.Next;
 194                if (currEntry.Key == key)
 195                {
 196                    return false;
 97                }
 098            }
 99
 2100            ref StringKeyEntry<TValue> entry = ref Entries[freeIndex];
 101
 2102            FreeListHead = entry.Next & 0x7FFFFFFF;
 2103            entry.Next = indexAtBucket;
 2104            entry.Key = key;
 2105            entry.Value = value;
 2106            entry.HashCode = hashCode;
 2107            Buckets[hashIndex] = freeIndex;
 108
 2109            ++Count;
 2110            return true;
 3111        }
 112
 113        /// <summary>
 114        /// Adds the key value pair to the dictionary, checking for duplicate entries and expanding if necessary.
 115        /// </summary>
 116        /// <param name="key">The key to add.</param>
 117        /// <param name="value">The value to add.</param>
 118        /// <returns>True if the entry was successfully created.</returns>
 119        public bool AddSafe(string key, TValue value)
 42120        {
 42121            if (key == null) throw new ArgumentNullException();
 122
 42123            int freeIndex = FreeListHead;
 124
 42125            if (freeIndex >= Buckets.Length)
 2126            {
 2127                ExpandWhenFull();
 2128            }
 129
 42130            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 42131            int hashIndex = hashCode % Buckets.Length;
 42132            int indexAtBucket = Buckets[hashIndex];
 133
 42134            int nextKeyIndex = indexAtBucket;
 135
 65136            while (nextKeyIndex != -1)
 23137            {
 23138                StringKeyEntry<TValue> currEntry = Entries[nextKeyIndex];
 23139                nextKeyIndex = currEntry.Next;
 23140                if (currEntry.Key == key)
 0141                {
 0142                    return false;
 143                }
 23144            }
 145
 42146            ref StringKeyEntry<TValue> entry = ref Entries[freeIndex];
 147
 42148            FreeListHead = entry.Next & 0x7FFFFFFF;
 42149            entry.Next = indexAtBucket;
 42150            entry.Key = key;
 42151            entry.Value = value;
 42152            entry.HashCode = hashCode;
 42153            Buckets[hashIndex] = freeIndex;
 154
 42155            ++Count;
 42156            return true;
 42157        }
 158
 159        /// <summary>
 160        /// Adds the key value pair to the dictionary, without checking for available capacity or duplicate entries.
 161        /// </summary>
 162        /// <param name="key">The key to add.</param>
 163        /// <param name="value">The value to add.</param>
 164        public void AddUnchecked(string key, TValue value)
 14165        {
 14166            int dataIndex = FreeListHead;
 14167            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 14168            int bucketIndex = hashCode % Buckets.Length;
 14169            int initialBucketValue = Buckets[bucketIndex];
 170
 14171            ref StringKeyEntry<TValue> entry = ref Entries[dataIndex];
 172
 14173            FreeListHead = entry.Next & 0x7FFFFFFF;
 14174            entry.Next = initialBucketValue;
 14175            entry.Key = key;
 14176            entry.Value = value;
 14177            entry.HashCode = hashCode;
 14178            Buckets[bucketIndex] = dataIndex;
 14179        }
 180
 181
 182        /// <summary>
 183        /// Checks if the dictionary contains the given key.
 184        /// </summary>
 185        /// <param name="key">The key to check for.</param>
 186        /// <returns>True if the dictionary contains the key.</returns>
 187        public bool ContainsKey(string key)
 2188        {
 2189            if (key == null) throw new ArgumentNullException();
 190
 2191            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 2192            int bucketIndex = hashCode % Buckets.Length;
 2193            int nextKeyIndex = Buckets[bucketIndex];
 194
 2195            while (nextKeyIndex != -1)
 1196            {
 1197                ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 198
 1199                if (currEntry.Key == key)
 1200                {
 1201                    return true;
 202                }
 203
 0204                nextKeyIndex = currEntry.Next;
 0205            }
 206
 1207            return false;
 2208        }
 209
 210        /// <summary>
 211        /// Resizes the dictionary with the assumption that it is full. Do not use otherwise.
 212        /// </summary>
 213        public void ExpandWhenFull()
 6214        {
 6215            int oldCapacity = Buckets.Length;
 6216            int nextPrimeCapacity = DictionaryPrimes.GetNextSize(oldCapacity);
 217
 6218            int[] newBuckets = new int[nextPrimeCapacity];
 456219            for (int i = 0; i < nextPrimeCapacity; i++)
 222220            {
 222221                newBuckets[i] = -1;
 222222            }
 223
 6224            StringKeyEntry<TValue>[] newEntries = new StringKeyEntry<TValue>[nextPrimeCapacity];
 6225            Array.Copy(Entries, 0, newEntries, 0, oldCapacity);
 226
 216227            for (int i = 0; i < oldCapacity; i++)
 102228            {
 102229                ref StringKeyEntry<TValue> entry = ref newEntries[i];
 230
 102231                int newBucketIndex = (entry.HashCode & 0x7FFFFFFF) % nextPrimeCapacity;
 232
 102233                int indexAtBucket = newBuckets[newBucketIndex];
 102234                entry.Next = indexAtBucket;
 102235                newBuckets[newBucketIndex] = i;
 102236            }
 237
 252238            for (int i = oldCapacity; i < nextPrimeCapacity; i++)
 120239            {
 120240                newEntries[i].Next = (1 << 31) | (i + 1);
 120241            }
 242
 6243            Buckets = newBuckets;
 6244            Entries = newEntries;
 6245        }
 246
 247        /// <summary>
 248        /// Expands the dictionary if it does not have enough empty space for <paramref name="capacityToReserve"/>.
 249        /// </summary>
 250        /// <param name="capacityToReserve"></param>
 251        public void Reserve(int capacityToReserve)
 1252        {
 1253            int oldCapacity = Entries.Length;
 1254            if (Count + capacityToReserve > oldCapacity)
 1255            {
 1256                int minCapacity = Count + capacityToReserve;
 1257                int nextPrimeCapacity = DictionaryPrimes.GetNextSize(minCapacity);
 258
 1259                int[] newBuckets = new int[nextPrimeCapacity];
 328260                for (int i = 0; i < nextPrimeCapacity; i++)
 163261                {
 163262                    newBuckets[i] = -1;
 163263                }
 264
 1265                StringKeyEntry<TValue>[] newEntries = new StringKeyEntry<TValue>[nextPrimeCapacity];
 1266                Array.Copy(Entries, 0, newEntries, 0, oldCapacity);
 267
 36268                for (int i = 0; i < oldCapacity; i++)
 17269                {
 17270                    ref StringKeyEntry<TValue> entry = ref newEntries[i];
 271
 17272                    if (entry.Key != null)
 0273                    {
 0274                        int newBucketIndex = (entry.HashCode & 0x7FFFFFFF) % nextPrimeCapacity;
 275
 0276                        int indexAtBucket = newBuckets[newBucketIndex];
 0277                        entry.Next = indexAtBucket;
 0278                        newBuckets[newBucketIndex] = i;
 0279                    }
 17280                }
 281
 294282                for (int i = oldCapacity; i < nextPrimeCapacity; i++)
 146283                {
 146284                    newEntries[i].Next = (1 << 31) | (i + 1);
 146285                }
 286
 1287                Buckets = newBuckets;
 1288                Entries = newEntries;
 1289            }
 1290        }
 291
 292        /// <summary>
 293        /// Finds the index of the entry corresponding to a key.
 294        /// </summary>
 295        /// <param name="key">The key to find the index of.</param>
 296        /// <returns>The index of the entry, or -1 if the entry does not exist.</returns>
 297        public int IndexOf(string key)
 62298        {
 62299            if (key == null) throw new ArgumentNullException();
 300
 62301            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 62302            int bucketIndex = hashCode % Buckets.Length;
 62303            int nextKeyIndex = Buckets[bucketIndex];
 304
 73305            while (nextKeyIndex != -1)
 72306            {
 72307                ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 308
 72309                if (currEntry.Key == key)
 61310                {
 61311                    return nextKeyIndex;
 312                }
 313
 11314                nextKeyIndex = currEntry.Next;
 11315            }
 316
 1317            return -1;
 62318        }
 319
 320        /// <summary>
 321        /// Replaces the value of the entry if the entry exists.
 322        /// </summary>
 323        /// <param name="key">The key of the entry to modify.</param>
 324        /// <param name="value">The new value of the entry.</param>
 325        /// <returns>True if the entry was found.</returns>
 326        public bool TryModifyValue(string key, TValue value)
 0327        {
 0328            if (key == null) throw new ArgumentNullException();
 329
 0330            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 0331            int bucketIndex = hashCode % Buckets.Length;
 0332            int nextKeyIndex = Buckets[bucketIndex];
 333
 0334            while (nextKeyIndex != -1)
 0335            {
 0336                ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 0337                nextKeyIndex = currEntry.Next;
 338
 0339                if (currEntry.Key == key)
 0340                {
 0341                    currEntry.Value = value;
 0342                    return true;
 343                }
 0344            }
 345
 0346            return false;
 0347        }
 348
 349        /// <summary>
 350        /// Removes the entry if it exists.
 351        /// </summary>
 352        /// <param name="key">The key to remove.</param>
 353        /// <returns>True if the entry was found.</returns>
 354        public bool TryRemove(string key)
 5355        {
 5356            if (key == null) throw new ArgumentNullException();
 357
 5358            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 5359            int bucketIndex = hashCode % Buckets.Length;
 5360            int indexAtBucket = Buckets[bucketIndex];
 5361            int indexOfKey = indexAtBucket;
 5362            int previousIndex = indexAtBucket;
 363
 5364            bool foundIndex = false;
 365
 6366            while (indexOfKey != -1)
 5367            {
 5368                ref StringKeyEntry<TValue> currEntry = ref Entries[indexOfKey];
 369
 5370                if (currEntry.Key == key)
 4371                {
 4372                    foundIndex = true;
 4373                    break;
 374                }
 375
 1376                previousIndex = indexOfKey;
 1377                indexOfKey = currEntry.Next;
 1378            }
 379
 5380            if (foundIndex)
 4381            {
 4382                ref StringKeyEntry<TValue> currEntry = ref Entries[indexOfKey];
 4383                int nextUsedIndex = currEntry.Next;
 4384                int nextFreeIndex = FreeListHead;
 385
 4386                currEntry.Key = null;
 4387                currEntry.Value = default;
 4388                currEntry.HashCode = 0;
 4389                currEntry.Next = nextFreeIndex | (1 << 31);
 4390                Entries[indexOfKey] = currEntry;
 4391                FreeListHead = indexOfKey;
 392
 4393                if (indexOfKey == indexAtBucket)
 3394                {
 3395                    Buckets[bucketIndex] = nextUsedIndex;
 3396                }
 397                else
 1398                {
 1399                    Entries[previousIndex].Next = nextUsedIndex;
 1400                }
 401
 4402                return true;
 403            }
 404
 1405            return false;
 5406        }
 407
 408        /// <summary>
 409        /// Removes the entry if it exists, but does not remove the value of the key value pair.
 410        /// </summary>
 411        /// <param name="key">The key to remove.</param>
 412        /// <returns>True if the entry was found.</returns>
 413        public bool TryRemoveNoValueClear(string key)
 0414        {
 0415            if (key == null) throw new ArgumentNullException();
 416
 0417            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 0418            int bucketIndex = hashCode % Buckets.Length;
 0419            int indexAtBucket = Buckets[bucketIndex];
 0420            int indexOfKey = indexAtBucket;
 0421            int previousIndex = indexAtBucket;
 422
 0423            bool foundIndex = false;
 424
 0425            while (indexOfKey != -1)
 0426            {
 0427                ref StringKeyEntry<TValue> currEntry = ref Entries[indexOfKey];
 428
 0429                if (currEntry.Key == key)
 0430                {
 0431                    foundIndex = true;
 0432                    break;
 433                }
 434
 0435                previousIndex = indexOfKey;
 0436                indexOfKey = currEntry.Next;
 0437            }
 438
 0439            if (foundIndex)
 0440            {
 0441                ref StringKeyEntry<TValue> currEntry = ref Entries[indexOfKey];
 0442                int nextUsedIndex = currEntry.Next;
 0443                int nextFreeIndex = FreeListHead;
 444
 0445                currEntry.Key = null;
 0446                currEntry.HashCode = 0;
 0447                currEntry.Next = nextFreeIndex | (1 << 31);
 0448                Entries[indexOfKey] = currEntry;
 0449                FreeListHead = indexOfKey;
 450
 0451                if (indexOfKey == indexAtBucket)
 0452                {
 0453                    Buckets[bucketIndex] = nextUsedIndex;
 0454                }
 455                else
 0456                {
 0457                    Entries[previousIndex].Next = nextUsedIndex;
 0458                }
 459
 0460                return true;
 461            }
 462
 0463            return false;
 0464        }
 465
 466        /// <summary>
 467        /// Attempts to get the value for the given key; returns true if key was found, false otherwise.
 468        /// </summary>
 469        /// <param name="key">The key to retrieve.</param>
 470        /// <param name="value">The value of the entry found.</param>
 471        /// <returns>True if the entry was found; false otherwise.</returns>
 472        public bool TryGetValue(string key, out TValue value)
 2473        {
 2474            if (key == null) throw new ArgumentNullException();
 475
 2476            int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 2477            int bucketIndex = hashCode % Buckets.Length;
 2478            int nextKeyIndex = Buckets[bucketIndex];
 479
 2480            while (nextKeyIndex != -1)
 1481            {
 1482                ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 1483                nextKeyIndex = currEntry.Next;
 484
 1485                if (currEntry.Key == key)
 1486                {
 1487                    value = currEntry.Value;
 1488                    return true;
 489                }
 0490            }
 491
 1492            value = default;
 1493            return false;
 2494        }
 495
 496        /// <summary>
 497        ///     Directly access a value by key.
 498        /// </summary>
 499        /// <param name="key">The target key to look for a value identified by.</param>
 500        /// <exception cref="ArgumentNullException">Thrown when a null <paramref name="key"/> is provided to lookup.</ex
 501        /// <exception cref="System.Collections.Generic.KeyNotFoundException">Thrown when the <paramref name="key"/> is 
 502        public TValue this[string key]
 503        {
 504            get
 6505            {
 6506                if (key == null) throw new ArgumentNullException();
 507
 6508                int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 6509                int bucketIndex = hashCode % Buckets.Length;
 6510                int nextKeyIndex = Buckets[bucketIndex];
 511
 512
 6513                while (nextKeyIndex != -1)
 6514                {
 6515                    ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 6516                    nextKeyIndex = currEntry.Next;
 517
 6518                    if (currEntry.Key == key)
 6519                    {
 6520                        return currEntry.Value;
 521                    }
 0522                }
 523
 0524                throw new System.Collections.Generic.KeyNotFoundException();
 6525            }
 526
 527            set
 38528            {
 38529                if (key == null) throw new ArgumentNullException();
 530
 38531                int freeIndex = FreeListHead;
 532
 38533                if (freeIndex >= Buckets.Length)
 2534                {
 2535                    ExpandWhenFull();
 2536                }
 537
 38538                int hashCode = key.GetStableHashCode() & 0x7FFFFFFF;
 38539                int bucketIndex = hashCode % Buckets.Length;
 38540                int indexAtBucket = Buckets[bucketIndex];
 541
 38542                int nextKeyIndex = indexAtBucket;
 543
 60544                while (nextKeyIndex != -1)
 22545                {
 22546                    ref StringKeyEntry<TValue> currEntry = ref Entries[nextKeyIndex];
 22547                    nextKeyIndex = currEntry.Next;
 22548                    if (currEntry.Key == key)
 0549                    {
 0550                        currEntry.Value = value;
 0551                        return;
 552                    }
 22553                }
 554
 38555                ref StringKeyEntry<TValue> entry = ref Entries[freeIndex];
 556
 38557                FreeListHead = entry.Next & 0x7FFFFFFF;
 38558                entry.Next = indexAtBucket;
 38559                entry.Key = key;
 38560                entry.Value = value;
 38561                entry.HashCode = hashCode;
 38562                Buckets[bucketIndex] = freeIndex;
 563
 38564                ++Count;
 38565            }
 566        }
 567
 568        /// <summary>
 569        /// Iterates the dictionary.
 570        /// </summary>
 571        /// <param name="iteratedIndexCount">The number of indices iterated so far - pass in 0 at the start of iteration
 572        /// <param name="iteratorVersion">The version when iteration started.</param>
 573        /// <param name="dictionaryVersion">The current version of the dictionary - update this on add, remove, or clear
 574        /// <param name="entry">The entry returned by the iterator</param>
 575        /// <returns>Whether the iterator found an entry, finished iteration, or could not continue due to an invalid ve
 576        public IteratorState MoveNext(ref int iteratedIndexCount, int iteratorVersion, in int dictionaryVersion, out Str
 5577        {
 5578            entry = default;
 579
 5580            if (iteratorVersion != dictionaryVersion)
 1581            {
 1582                return IteratorState.InvalidVersion;
 583            }
 584
 19585            while (iteratedIndexCount < Entries.Length)
 18586            {
 18587                ref StringKeyEntry<TValue> keyEntry = ref Entries[iteratedIndexCount];
 18588                iteratedIndexCount++;
 589
 18590                if (keyEntry.Key != null)
 3591                {
 3592                    entry = keyEntry;
 3593                    return IteratorState.FoundEntry;
 594                }
 15595            }
 596
 1597            return IteratorState.Finished;
 5598        }
 599
 600        /// <summary>
 601        /// Iterates the dictionary.
 602        /// NOTE: if you suspect the dictionary might be modified while iterating, this will not catch the error -- use 
 603        /// </summary>
 604        /// <param name="iteratedIndexCount">The number of indices iterated so far - pass in 0 at the start of iteration
 605        /// <param name="entry">The entry returned by the iterator</param>
 606        /// <returns>Whether or not the iterator found an entry</returns>
 607        public bool MoveNext(ref int iteratedIndexCount, out StringKeyEntry<TValue> entry)
 3608        {
 3609            entry = default;
 610
 18611            while (iteratedIndexCount < Entries.Length)
 17612            {
 17613                ref StringKeyEntry<TValue> keyEntry = ref Entries[iteratedIndexCount];
 17614                iteratedIndexCount++;
 615
 17616                if (keyEntry.Key != null)
 2617                {
 2618                    entry = keyEntry;
 619
 2620                    return true;
 621                }
 15622            }
 623
 1624            return false;
 3625        }
 626
 627        /// <summary>
 628        /// Iterates the dictionary.
 629        /// NOTE: if you suspect the dictionary might be modified while iterating, this will not catch the error -- use 
 630        /// </summary>
 631        /// <param name="iteratedIndexCount">The number of indices iterated so far - pass in 0 at the start of iteration
 632        /// <returns>Whether or not the iterator found an entry</returns>
 633        public bool MoveNext(ref int iteratedIndexCount)
 0634        {
 0635            while (iteratedIndexCount < Entries.Length)
 0636            {
 0637                ref StringKeyEntry<TValue> keyEntry = ref Entries[iteratedIndexCount];
 0638                iteratedIndexCount++;
 639
 0640                if (keyEntry.Key != null)
 0641                {
 0642                    return true;
 643                }
 0644            }
 645
 0646            return false;
 0647        }
 648
 649        /// <summary>
 650        /// Clears the dictionary.
 651        /// </summary>
 652        public void Clear()
 4653        {
 4654            int length = Entries.Length;
 655
 144656            for (int i = 0; i < length; i++)
 68657            {
 68658                Buckets[i] = -1;
 68659            }
 660
 144661            for (int i = 0; i < length; i++)
 68662            {
 68663                ref StringKeyEntry<TValue> entryAt = ref Entries[i];
 68664                entryAt.Next = (1 << 31) | (i + 1);
 68665                entryAt.Key = null;
 68666                entryAt.Value = default;
 68667                entryAt.HashCode = 0;
 68668            }
 669
 4670            FreeListHead = 0;
 4671            Count = 0;
 4672        }
 673    }
 674
 675    [Serializable]
 676    public struct StringKeyEntry<T>
 677    {
 678        public string Key;
 679        public T Value;
 680        public int Next;
 681        public int HashCode;
 682    }
 683}