< Summary

Information
Class: SwiftCollections.MemberNotNullAttribute
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftDictionary.cs
Line coverage
100%
Covered lines: 2
Uncovered lines: 0
Coverable lines: 2
Total lines: 1423
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)100%11100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftDictionary.cs

#LineLine coverage
 1//=======================================================================
 2// SwiftDictionary.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024–present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using Chronicler;
 9using MemoryPack;
 10using SwiftCollections.Diagnostics;
 11using SwiftCollections.Utility;
 12using System;
 13using System.Collections;
 14using System.Collections.Generic;
 15using System.Runtime.CompilerServices;
 16using System.Text.Json.Serialization;
 17
 18namespace SwiftCollections;
 19
 20/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null 
 21[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
 22#if SYSTEM_PRIVATE_CORELIB
 23    public
 24#else
 25internal
 26#endif
 27    sealed class MemberNotNullAttribute : Attribute
 28{
 29    /// <summary>Initializes the attribute with a field or property member.</summary>
 30    /// <param name="member">
 31    /// The field or property member that is promised to be not-null.
 32    /// </param>
 233    public MemberNotNullAttribute(string member) => Members = new[] { member };
 34
 35    /// <summary>Initializes the attribute with the list of field and property members.</summary>
 36    /// <param name="members">
 37    /// The list of field and property members that are promised to be not-null.
 38    /// </param>
 239    public MemberNotNullAttribute(params string[] members) => Members = members;
 40
 41    /// <summary>Gets field or property member names.</summary>
 42    public string[] Members { get; }
 43}
 44
 45/// <summary>
 46/// A high-performance, memory-efficient dictionary providing lightning-fast O(1) operations for addition, retrieval, an
 47/// </summary>
 48/// <typeparam name="TKey">Specifies the type of keys in the dictionary.</typeparam>
 49/// <typeparam name="TValue">Specifies the type of values in the dictionary.</typeparam>
 50/// <remarks>
 51/// The comparer is not serialized. After deserialization the dictionary reverts
 52/// to the same default comparer selection used by a new instance. String keys
 53/// use SwiftCollections' deterministic default comparer. Object keys use a
 54/// SwiftCollections comparer that hashes strings deterministically, while other
 55/// object-key determinism still depends on the underlying key type's
 56/// <see cref="object.GetHashCode()"/> implementation. Other key types use
 57/// <see cref="EqualityComparer{TKey}.Default"/>.
 58///
 59/// If a custom comparer is required it can be reapplied using
 60/// <see cref="SetComparer(IEqualityComparer{TKey})"/>.
 61/// </remarks>
 62[Serializable]
 63[JsonConverter(typeof(StateJsonConverterFactory))]
 64[MemoryPackable]
 65public partial class SwiftDictionary<TKey, TValue> : IStateBacked<SwiftDictionaryState<TKey, TValue>>, IDictionary<TKey,
 66    where TKey : notnull
 67{
 68    #region Constants
 69
 70    /// <summary>
 71    /// The default initial capacity of the dictionary.
 72    /// </summary>
 73    public const int DefaultCapacity = 8;
 74
 75    /// <summary>
 76    /// Determines the maximum allowable load factor before resizing the hash set to maintain performance.
 77    /// </summary>
 78    private const double _LoadFactorThreshold = 0.82;
 79
 80    #endregion
 81
 82    #region Fields
 83
 84    /// <summary>
 85    /// The array containing the entries of the dictionary.
 86    /// </summary>
 87    protected Entry[] _entries;
 88
 89    /// <summary>
 90    /// The total number of entries in the dictionary
 91    /// </summary>
 92    private int _count;
 93
 94    /// <summary>
 95    /// The index of the last used entry in the dictionary.
 96    /// </summary>
 97    private int _lastIndex;
 98
 99    /// <summary>
 100    /// A mask used for efficiently computing the entry arrayIndex from a hash code.
 101    /// This is typically the size of the entry array minus one, assuming the size is a power of two.
 102    /// </summary>
 103    private int _entryMask;
 104
 105    /// <summary>
 106    /// The comparer used to determine equality of keys and to generate hash codes.
 107    /// </summary>
 108    protected IEqualityComparer<TKey> _comparer;
 109
 110    /// <summary>
 111    /// Specifies the dynamic growth factor for resizing, adjusted based on recent usage patterns.
 112    /// </summary>
 113    private int _adaptiveResizeFactor;
 114
 115    /// <summary>
 116    /// Tracks the count threshold at which the hash set should resize based on the load factor.
 117    /// </summary>
 118    private uint _nextResizeCount;
 119
 120    /// <summary>
 121    /// Represents the moving average of the fill rate, used to dynamically adjust resizing behavior.
 122    /// </summary>
 123    private double _movingFillRate;
 124
 125    /// <summary>
 126    /// The maximum number of steps allowed during probing to resolve collisions.
 127    /// </summary>
 128    private int _maxStepCount;
 129
 130    /// <summary>
 131    /// A version counter used to track modifications to the dictionary.
 132    /// Incremented on mutations to detect changes during enumeration and ensure enumerator validity.
 133    /// </summary>
 134    [NonSerialized]
 135    protected uint _version;
 136
 137    /// <summary>
 138    /// An object that can be used to synchronize access to the SwiftDictionary.
 139    /// </summary>
 140    [NonSerialized]
 141    private object? _syncRoot;
 142
 143    #endregion
 144
 145    #region Nested Types
 146
 147    /// <summary>
 148    /// Represents a single key-value pair in the dictionary, including its hash code for quick access.
 149    /// </summary>
 150    protected struct Entry
 151    {
 152        /// <summary>
 153        /// Gets or sets the key associated with this instance.
 154        /// </summary>
 155        public TKey Key;
 156
 157        /// <summary>
 158        /// Gets or sets the value associated with this instance.
 159        /// </summary>
 160        public TValue Value;
 161
 162        /// <summary>
 163        /// Gets or sets the lower 31 bits of the hash code associated with this entry.
 164        /// </summary>
 165        /// <remarks>
 166        /// A value of -1 indicates that the entry is a deleted probe tombstone.
 167        /// Only the lower 31 bits are used; the highest bit is reserved.</remarks>
 168        public int HashCode;
 169
 170        /// <summary>
 171        /// Indicates whether the item is currently in use.
 172        /// </summary>
 173        public bool IsUsed;
 174    }
 175
 176    #endregion
 177
 178    #region Constructors
 179
 180    /// <summary>
 181    /// Initialize a new instance of <see cref="SwiftDictionary{TKey, TValue}"/> with customizable capacity and comparer
 182    /// </summary>
 183    public SwiftDictionary() : this(DefaultCapacity, null) { }
 184
 185    /// <inheritdoc cref="SwiftDictionary()"/>
 186    public SwiftDictionary(int capacity, IEqualityComparer<TKey>? comparer = null)
 187    {
 188        Initialize(capacity, comparer);
 189
 190        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 191        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 192    }
 193
 194    /// <inheritdoc cref="SwiftDictionary()"/>
 195    public SwiftDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey>? comparer = null)
 196    {
 197        SwiftThrowHelper.ThrowIfNull(dictionary, nameof(dictionary));
 198
 199        Initialize(dictionary.Count, comparer);
 200
 201        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 202        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 203
 204        foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
 205            InsertIfNotExist(kvp.Key, kvp.Value);
 206    }
 207
 208    /// <inheritdoc cref="SwiftDictionary()"/>
 209    public SwiftDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey>? comparer = null)
 210    {
 211        SwiftThrowHelper.ThrowIfNull(collection, nameof(collection));
 212
 213        int count = (collection as ICollection<KeyValuePair<TKey, TValue>>)?.Count ?? DefaultCapacity;
 214        // Dynamic padding based on collision estimation
 215        int size = (int)(count / _LoadFactorThreshold);
 216        Initialize(size, comparer);
 217
 218        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 219        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 220
 221        foreach (KeyValuePair<TKey, TValue> kvp in collection)
 222            InsertIfNotExist(kvp.Key, kvp.Value);
 223    }
 224
 225    ///  <summary>
 226    ///  Initializes a new instance of the <see cref="SwiftDictionary{TKey, TValue}"/> class with the specified <see cre
 227    ///  </summary>
 228    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 229    [MemoryPackConstructor]
 230    public SwiftDictionary(SwiftDictionaryState<TKey, TValue> state)
 231    {
 232        State = state;
 233
 234        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 235        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 236    }
 237
 238    #endregion
 239
 240    #region Properties
 241
 242    /// <summary>
 243    /// Gets the number of elements contained in the dictionary.
 244    /// </summary>
 245    [JsonIgnore]
 246    [MemoryPackIgnore]
 247    public int Count => _count;
 248
 249    /// <summary>
 250    /// Gets the total number of elements that the collection can hold without resizing.
 251    /// </summary>
 252    [JsonIgnore]
 253    [MemoryPackIgnore]
 254    public int Capacity => _entries.Length;
 255
 256    /// <summary>
 257    /// Gets the equality comparer used to determine equality of keys in the collection.
 258    /// </summary>
 259    [JsonIgnore]
 260    [MemoryPackIgnore]
 261    public IEqualityComparer<TKey> Comparer => _comparer;
 262
 263    /// <summary>
 264    /// Gets or sets the value associated with the specified key.
 265    /// </summary>
 266    /// <remarks>
 267    /// Getting a value with a key that does not exist will throw an exception.
 268    /// Setting a value for a key that does not exist will add a new entry with the specified key and value.
 269    /// </remarks>
 270    /// <param name="key">The key whose value to get or set.</param>
 271    [JsonIgnore]
 272    [MemoryPackIgnore]
 273    public TValue this[TKey key]
 274    {
 275        get
 276        {
 277            int index = FindEntry(key);
 278            SwiftThrowHelper.ThrowIfKeyInvalid(index, key);
 279            return _entries[index].Value;
 280        }
 281        set
 282        {
 283            int index = FindEntry(key);
 284            if (index >= 0)
 285                _entries[index].Value = value;
 286            else
 287            {
 288                CheckLoadThreshold();
 289                InsertIfNotExist(key, value);
 290            }
 291        }
 292    }
 293
 294    /// <inheritdoc/>
 295    [JsonIgnore]
 296    [MemoryPackIgnore]
 297    object? IDictionary.this[object obj]
 298    {
 299        get
 300        {
 301            SwiftThrowHelper.ThrowIfNull(obj, nameof(obj));
 302
 303            if (obj is TKey key)
 304            {
 305                int index = FindEntry(key);
 306                if (index >= 0) return _entries[index].Value;
 307            }
 308            return null;
 309        }
 310        set
 311        {
 312            SwiftThrowHelper.ThrowIfNullAndNullsAreIllegal(value, default(TValue));
 313            try
 314            {
 315                TKey tempKey = (TKey)obj;
 316                try
 317                {
 318                    this[tempKey] = (TValue)value!;
 319                }
 320                catch (InvalidCastException)
 321                {
 322                    throw new ArgumentException($"Value {value} does not match expected {typeof(TValue)}");
 323                }
 324            }
 325            catch (InvalidCastException)
 326            {
 327                throw new ArgumentException($"Key {obj} does not match expected {typeof(TKey)}");
 328            }
 329        }
 330    }
 331
 332    /// <summary>
 333    /// The collection containing the keys of the dictionary.
 334    /// </summary>
 335    [JsonIgnore]
 336    [MemoryPackIgnore]
 337    private KeyCollection? _keyCollection;
 338
 339    /// <inheritdoc/>
 340    [JsonIgnore]
 341    [MemoryPackIgnore]
 342    public ICollection<TKey> Keys => _keyCollection ??= new KeyCollection(this);
 343
 344    [JsonIgnore]
 345    [MemoryPackIgnore]
 346    ICollection IDictionary.Keys => _keyCollection ??= new KeyCollection(this);
 347
 348    /// <summary>
 349    /// The collection containing the values of the dictionary.
 350    /// </summary>
 351    [JsonIgnore]
 352    [MemoryPackIgnore]
 353    private ValueCollection? _valueCollection;
 354
 355    /// <inheritdoc/>
 356    [JsonIgnore]
 357    [MemoryPackIgnore]
 358    public ICollection<TValue> Values => _valueCollection ??= new ValueCollection(this);
 359
 360    [JsonIgnore]
 361    [MemoryPackIgnore]
 362    ICollection IDictionary.Values => _valueCollection ??= new ValueCollection(this);
 363
 364    [JsonIgnore]
 365    [MemoryPackIgnore]
 366    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
 367
 368    [JsonIgnore]
 369    [MemoryPackIgnore] bool IDictionary.IsReadOnly => false;
 370    bool IDictionary.IsFixedSize => false;
 371
 372    [JsonIgnore]
 373    [MemoryPackIgnore]
 374    bool ICollection.IsSynchronized => false;
 375
 376    /// <inheritdoc/>
 377    [JsonIgnore]
 378    [MemoryPackIgnore]
 379    public object SyncRoot => _syncRoot ??= new object();
 380
 381    /// <summary>
 382    /// Gets or sets the current state of the dictionary, including all key-value pairs.
 383    /// </summary>
 384    /// <remarks>
 385    /// The state can be used to serialize or restore the contents of the dictionary.
 386    /// Setting this property replaces the entire contents of the dictionary with the provided state.
 387    /// The setter is intended for internal use and is not accessible to external callers.
 388    /// </remarks>
 389    [JsonInclude]
 390    [MemoryPackInclude]
 391    public SwiftDictionaryState<TKey, TValue> State
 392    {
 393        get
 394        {
 395            if (_count == 0)
 396                return new SwiftDictionaryState<TKey, TValue>(Array.Empty<KeyValuePair<TKey, TValue>>());
 397
 398            var items = new KeyValuePair<TKey, TValue>[_count];
 399            CopyTo(items, 0);
 400
 401            return new SwiftDictionaryState<TKey, TValue>(items);
 402        }
 403        internal set
 404        {
 405            SwiftThrowHelper.ThrowIfNull(value.Items, nameof(value.Items));
 406
 407            var items = value.Items;
 408            int count = items.Length;
 409
 410            if (count == 0)
 411            {
 412                Initialize(DefaultCapacity);
 413                _count = 0;
 414                _version = 0;
 415                return;
 416            }
 417
 418            int size = (int)(count / _LoadFactorThreshold);
 419            Initialize(size);
 420
 421            foreach (var kvp in items)
 422                InsertIfNotExist(kvp.Key, kvp.Value);
 423
 424            _version = 0;
 425        }
 426    }
 427
 428    #endregion
 429
 430    #region Collection Manipulation
 431
 432    /// <summary>
 433    /// Attempts to add the specified key and value to the dictionary.
 434    /// </summary>
 435    /// <param name="key">The key of the element to add.</param>
 436    /// <param name="value">The value of the element to add.</param>
 437    /// <returns>
 438    /// true if the key/value pair was added to the dictionary successfully;
 439    /// false if the key already exists.
 440    /// </returns>
 441    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 442    public virtual bool Add(TKey key, TValue value)
 443    {
 444        CheckLoadThreshold();
 445        return InsertIfNotExist(key, value);
 446    }
 447
 448    /// <inheritdoc/>
 449    public void Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
 450
 451    void IDictionary<TKey, TValue>.Add(TKey key, TValue value) => Add(key, value);
 452
 453    /// <inheritdoc/>
 454    public void Add(object key, object? value)
 455    {
 456        SwiftThrowHelper.ThrowIfNullAndNullsAreIllegal(value, default(TValue));
 457
 458        try
 459        {
 460            TKey tempKey = (TKey)key;
 461            try
 462            {
 463                Add(tempKey, (TValue)value!);
 464            }
 465            catch (InvalidCastException)
 466            {
 467                throw new ArgumentException($"Value {value} does not match expected {typeof(TValue)}");
 468            }
 469        }
 470        catch (InvalidCastException)
 471        {
 472            throw new ArgumentException($"Key {key} does not match expected {typeof(TKey)}");
 473        }
 474    }
 475
 476    /// <summary>
 477    /// Inserts a key/value pair into the dictionary. If the key already exists and
 478    /// pair is added, or the method returns false if the key already exists.
 479    /// </summary>
 480    /// <param name="key">The key to insert or update.</param>
 481    /// <param name="value">The value to insert or update.</param>
 482    /// <returns>
 483    /// true if the key/value pair was added to the dictionary successfully;
 484    /// false if the key already exists.
 485    /// </returns>
 486    /// <exception cref="ArgumentNullException">Thrown when the key is null.</exception>
 487    internal virtual bool InsertIfNotExist(TKey key, TValue value)
 488    {
 489        SwiftThrowHelper.ThrowIfNullGeneric(key, nameof(key));
 490
 491        int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
 492        int entryIndex = hashCode & _entryMask;
 493
 494        int firstDeletedIndex = -1;
 495        int step = 1;
 496        int probeLimit = _entries.Length;
 497        while ((uint)step <= (uint)probeLimit)
 498        {
 499            ref Entry entry = ref _entries[entryIndex];
 500            if (entry.IsUsed)
 501            {
 502                if (entry.HashCode == hashCode && _comparer.Equals(entry.Key, key))
 503                    return false; // Item already exists
 504            }
 505            else if (entry.HashCode == -1)
 506            {
 507                if (firstDeletedIndex < 0) firstDeletedIndex = entryIndex;
 508            }
 509            else
 510            {
 511                break;
 512            }
 513
 514            entryIndex = (entryIndex + step * step) & _entryMask; // Quadratic probing
 515            step++;
 516        }
 517
 518        if (firstDeletedIndex >= 0)
 519            entryIndex = firstDeletedIndex;
 520        else if ((uint)step > (uint)probeLimit)
 521        {
 522            Resize(_entries.Length * _adaptiveResizeFactor);
 523            return InsertIfNotExist(key, value);
 524        }
 525
 526        if ((uint)entryIndex > (uint)_lastIndex) _lastIndex = entryIndex;
 527
 528        _entries[entryIndex].HashCode = hashCode;
 529        _entries[entryIndex].Key = key;
 530        _entries[entryIndex].Value = value;
 531        _entries[entryIndex].IsUsed = true;
 532        _count++;
 533        _version++;
 534
 535        if ((uint)step > (uint)_maxStepCount)
 536        {
 537            _maxStepCount = step;
 538            if (_comparer is not IRandomedEqualityComparer && _maxStepCount > 100)
 539                SwitchToRandomizedComparer();  // Attempt to recompute hash code with potential randomization for better
 540        }
 541
 542
 543        return true;
 544    }
 545
 546    /// <inheritdoc/>
 547    public virtual bool Remove(TKey key)
 548    {
 549        if (key == null) return false;
 550
 551        int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
 552        int entryIndex = hashCode & _entryMask;
 553
 554        int step = 0;
 555        while ((uint)step <= (uint)_lastIndex)
 556        {
 557            ref Entry entry = ref _entries[entryIndex];
 558            // Stop probing if an unused entry is found (not deleted)
 559            if (!entry.IsUsed && entry.HashCode != -1)
 560                return false;
 561            if (entry.IsUsed && entry.HashCode == hashCode && _comparer.Equals(entry.Key, key))
 562            {
 563                // Mark entry as deleted
 564                entry.IsUsed = false;
 565                entry.Key = default!;
 566                entry.Value = default!;
 567                entry.HashCode = -1;
 568                _count--;
 569                if ((uint)_count == 0) _lastIndex = 0;
 570                _version++;
 571                return true;
 572            }
 573
 574            // Move to the next entry using linear probing
 575            step++;
 576            entryIndex = (entryIndex + step * step) & _entryMask;
 577        }
 578        return false; // Item not found after full loop
 579    }
 580
 581    void IDictionary.Remove(object obj)
 582    {
 583        SwiftThrowHelper.ThrowIfNull(obj, nameof(obj));
 584        if (obj is TKey key) Remove(key);
 585    }
 586
 587    /// <inheritdoc/>
 588    public bool Remove(KeyValuePair<TKey, TValue> item)
 589    {
 590        int index = FindEntry(item.Key);
 591        if (index >= 0 && EqualityComparer<TValue>.Default.Equals(_entries[index].Value, item.Value))
 592        {
 593            Remove(item.Key);
 594            return true;
 595        }
 596        return false;
 597    }
 598
 599    /// <inheritdoc/>
 600    public virtual void Clear()
 601    {
 602        if ((uint)_count == 0) return;
 603
 604        for (uint i = 0; i <= (uint)_lastIndex; i++)
 605        {
 606            // Clear is a full reset, not a delete; future probes must be able to stop
 607            // at these now-empty slots instead of treating them as tombstones.
 608            _entries[i].HashCode = 0;
 609            _entries[i].Key = default!;
 610            _entries[i].Value = default!;
 611            _entries[i].IsUsed = false;
 612        }
 613
 614        _count = 0;
 615        _lastIndex = 0;
 616        _maxStepCount = 0;
 617        _movingFillRate = 0;
 618        _adaptiveResizeFactor = 4;
 619
 620        _version++;
 621    }
 622
 623    #endregion
 624
 625    #region Capacity Management
 626
 627    /// <summary>
 628    /// Ensures that the dictionary is resized when the current load factor exceeds the predefined threshold.
 629    /// </summary>
 630    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 631    protected void CheckLoadThreshold()
 632    {
 633        if ((uint)_count >= _nextResizeCount)
 634            Resize(_entries.Length * _adaptiveResizeFactor);
 635    }
 636
 637    /// <summary>
 638    /// Ensures that the dictionary can hold up to the specified number of entries, if not it resizes.
 639    /// </summary>
 640    /// <param name="capacity">The minimum capacity to ensure.</param>
 641    /// <returns>The new capacity of the dictionary.</returns>
 642    /// <exception cref="ArgumentOutOfRangeException">The capacity is less than zero.</exception>
 643    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 644    public void EnsureCapacity(int capacity)
 645    {
 646        capacity = SwiftHashTools.NextPowerOfTwo(capacity);  // Capacity must be a power of 2 for proper masking
 647        if (capacity > _entries.Length)
 648            Resize(capacity);
 649    }
 650
 651    /// <summary>
 652    /// Resizes the internal arrays to the specified new size.
 653    /// </summary>
 654    /// <param name="newSize">The new size for the internal arrays.</param>
 655    private void Resize(int newSize)
 656    {
 657        Entry[] newEntries = new Entry[newSize];
 658        int newMask = newSize - 1;
 659
 660        int lastIndex = 0;
 661        for (uint i = 0; i <= (uint)_lastIndex; i++)
 662        {
 663            if (_entries[i].IsUsed) // Only rehash valid entries
 664            {
 665                ref Entry oldEntry = ref _entries[i];
 666                int newIndex = oldEntry.HashCode & newMask;
 667                // If current entry not available, perform Quadratic probing to find the next available entry
 668                int step = 1;
 669                while (newEntries[newIndex].IsUsed)
 670                {
 671                    newIndex = (newIndex + step * step) & newMask;
 672                    step++;
 673                }
 674                newEntries[newIndex] = oldEntry;
 675                if (newIndex > lastIndex) lastIndex = newIndex;
 676            }
 677        }
 678
 679        _lastIndex = lastIndex;
 680
 681        CalculateAdaptiveResizeFactors(newSize);
 682
 683        _entries = newEntries;
 684        _entryMask = newMask;
 685
 686        _version++;
 687    }
 688
 689    /// <summary>
 690    /// Sets the capacity of a <see cref="SwiftDictionary{TKey, TValue}"/> to the actual
 691    /// number of elements it contains, rounded up to a nearby next power of 2 value.
 692    /// </summary>
 693    public void TrimExcess()
 694    {
 695        int newSize = _count <= DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(_count);
 696        if (newSize >= _entries.Length) return;
 697
 698        Entry[] newEntries = new Entry[newSize];
 699        int newMask = newSize - 1;
 700
 701        int lastIndex = 0;
 702        for (int i = 0; i <= (uint)_lastIndex; i++)
 703        {
 704            if (_entries[i].IsUsed)
 705            {
 706                ref Entry oldEntry = ref _entries[i];
 707                int newIndex = oldEntry.HashCode & newMask;
 708                // If current entry not available, perform quadratic probing to find the next available entry
 709                int step = 1;
 710                while (newEntries[newIndex].IsUsed)
 711                {
 712                    newIndex = (newIndex + step * step) & newMask;
 713                    step++;
 714                }
 715                newEntries[newIndex] = oldEntry;
 716                if (newIndex > lastIndex) lastIndex = newIndex;
 717            }
 718        }
 719
 720        _lastIndex = lastIndex;
 721
 722        CalculateAdaptiveResizeFactors(newSize);
 723
 724        _entryMask = newMask;
 725        _entries = newEntries;
 726
 727        _version++;
 728    }
 729
 730    /// <summary>
 731    ///  Updates adaptive resize parameters based on the current fill rate to balance memory usage and performance.
 732    /// </summary>
 733    /// <param name="newSize"></param>
 734    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 735    private void CalculateAdaptiveResizeFactors(int newSize)
 736    {
 737        // Calculate current fill rate and update moving average
 738        double currentFillRate = (double)_count / newSize;
 739        _movingFillRate = _movingFillRate == 0 ? currentFillRate : (_movingFillRate * 0.7 + currentFillRate * 0.3);
 740
 741        if (_movingFillRate > 0.3f)
 742            _adaptiveResizeFactor = 2; // Growth stabilizing
 743        else if (_movingFillRate < 0.28f)
 744            _adaptiveResizeFactor = 4; // Rapid growth
 745
 746        // Reset the resize threshold based on the new size
 747        _nextResizeCount = (uint)(newSize * _LoadFactorThreshold);
 748    }
 749
 750    #endregion
 751
 752    #region Utility Methods
 753
 754    /// <summary>
 755    /// Initializes the dictionary with the specified capacity.
 756    /// </summary>
 757    /// <param name="capacity">The initial number of elements that the dictionary can contain.</param>
 758    /// <param name="comparer">The comparer to use for the dictionary.</param>
 759    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 760    [MemberNotNull(nameof(_comparer))]
 761    private void Initialize(int capacity, IEqualityComparer<TKey>? comparer = null)
 762    {
 763        _comparer = SwiftHashTools.GetDefaultEqualityComparer(comparer);
 764
 765        int size = capacity < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(capacity);
 766        _entries = new Entry[size];
 767        _entryMask = size - 1;
 768
 769        _nextResizeCount = (uint)(size * _LoadFactorThreshold);
 770        _adaptiveResizeFactor = 4; // start agressive
 771        _movingFillRate = 0.0;
 772    }
 773
 774    /// <summary>
 775    /// Determines whether the dictionary contains an element with the specified key.
 776    /// </summary>
 777    /// <param name="key">The key to locate in the dictionary.</param>
 778    /// <returns>true if the dictionary contains an element with the specified key; otherwise, false.</returns>
 779    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 780    public bool ContainsKey(TKey key) => FindEntry(key) >= 0;
 781
 782    bool IDictionary.Contains(object obj)
 783    {
 784        SwiftThrowHelper.ThrowIfNull(obj, nameof(obj));
 785
 786        if (obj is TKey key) return ContainsKey(key);
 787        return false;
 788    }
 789
 790    /// <inheritdoc/>
 791    public bool Contains(KeyValuePair<TKey, TValue> item)
 792    {
 793        int index = FindEntry(item.Key);
 794        if (index >= 0 && EqualityComparer<TValue>.Default.Equals(_entries[index].Value, item.Value))
 795            return true;
 796        return false;
 797    }
 798
 799    /// <inheritdoc/>
 800    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 801    public bool TryGetValue(TKey key, out TValue value)
 802    {
 803        int index = FindEntry(key);
 804        if (index >= 0)
 805        {
 806            value = _entries[index].Value;
 807            return true;
 808        }
 809        value = default!;
 810        return false;
 811    }
 812
 813    /// <summary>
 814    /// Copies the elements of the collection to the specified array, starting at the given array index.
 815    /// </summary>
 816    /// <param name="array">
 817    /// The one-dimensional array of key/value pairs that is the destination of the elements copied from the collection.
 818    /// The array must have zero-based indexing.
 819    /// </param>
 820    /// <param name="arrayIndex">The zero-based index in the destination array at which copying begins.</param>
 821    /// <exception cref="ArgumentOutOfRangeException">Thrown if arrayIndex is less than 0 or greater than the length of 
 822    /// <exception cref="ArgumentException">
 823    /// Thrown if the number of elements in the source collection is greater than the available space from arrayIndex to
 824    /// the end of the destination array.
 825    /// </exception>
 826    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
 827    {
 828        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 829        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 830        SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _count, nameof(array), "Insufficient space in the t
 831
 832        for (uint i = 0; i <= (uint)_lastIndex; i++)
 833        {
 834            if (_entries[i].IsUsed)
 835                array[arrayIndex++] = new KeyValuePair<TKey, TValue>(_entries[i].Key, _entries[i].Value);
 836        }
 837    }
 838
 839    /// <inheritdoc/>
 840    public void CopyTo(Array array, int arrayIndex)
 841    {
 842        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 843        SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Multidimensional array not supported");
 844        SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Non-zero lower bound");
 845        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 846        SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _count, nameof(array), "Insufficient space in the t
 847
 848        if (array is KeyValuePair<TKey, TValue>[] pairs)
 849            ((ICollection<KeyValuePair<TKey, TValue>>)this).CopyTo(pairs, arrayIndex);
 850        else if (array is DictionaryEntry[] dictEntryArray)
 851            CopyToDictionaryEntries(dictEntryArray, arrayIndex);
 852        else
 853            CopyToObjects(array, arrayIndex);
 854    }
 855
 856    private void CopyToDictionaryEntries(DictionaryEntry[] array, int arrayIndex)
 857    {
 858        for (uint i = 0; i <= (uint)_lastIndex; i++)
 859        {
 860            if (_entries[i].IsUsed)
 861                array[arrayIndex++] = new DictionaryEntry(_entries[i].Key, _entries[i].Value);
 862        }
 863    }
 864
 865    private void CopyToObjects(Array array, int arrayIndex)
 866    {
 867        if (array is not object[] objects)
 868            throw new ArgumentException("Invalid array type", nameof(array));
 869
 870        try
 871        {
 872            CopyToObjects(objects, arrayIndex);
 873        }
 874        catch (ArrayTypeMismatchException)
 875        {
 876            throw new ArgumentException("Invalid array type", nameof(array));
 877        }
 878    }
 879
 880    private void CopyToObjects(object[] array, int arrayIndex)
 881    {
 882        for (uint i = 0; i <= (uint)_lastIndex; i++)
 883        {
 884            if (_entries[i].IsUsed)
 885                array[arrayIndex++] = new KeyValuePair<TKey, TValue>(_entries[i].Key, _entries[i].Value);
 886        }
 887    }
 888
 889    /// <summary>
 890    /// Sets a new comparer for the dictionary and rehashes the entries.
 891    /// </summary>
 892    /// <param name="comparer">The new comparer to use.</param>
 893    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 894    public void SetComparer(IEqualityComparer<TKey> comparer)
 895    {
 896        SwiftThrowHelper.ThrowIfNull(comparer, nameof(comparer));
 897        if (ReferenceEquals(comparer, _comparer))
 898            return;
 899
 900        _comparer = comparer;
 901        RehashEntries();
 902        _maxStepCount = 0;
 903    }
 904
 905    /// <summary>
 906    /// Switches the dictionary's comparer to a randomized comparer to mitigate the effects of high collision counts,
 907    /// and rehashes all entries using the new comparer to redistribute them across <see cref="_entries"/>.
 908    /// </summary>
 909    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 910    private void SwitchToRandomizedComparer()
 911    {
 912        if (SwiftHashTools.IsWellKnownEqualityComparer(_comparer))
 913            _comparer = (IEqualityComparer<TKey>)SwiftHashTools.GetSwiftEqualityComparer(_comparer);
 914        else return; // nothing to do here
 915
 916        RehashEntries();
 917        _maxStepCount = 0;
 918
 919        _version++;
 920    }
 921
 922    /// <summary>
 923    /// Reconstructs the internal entry structure to align with updated hash codes, ensuring efficient access and storag
 924    /// </summary>
 925    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 926    private void RehashEntries()
 927    {
 928        Entry[] newEntries = new Entry[_entries.Length];
 929        int newMask = newEntries.Length - 1;
 930
 931        int lastIndex = 0;
 932        for (uint i = 0; i <= (uint)_lastIndex; i++)
 933        {
 934            if (_entries[i].IsUsed)
 935            {
 936                ref Entry oldEntry = ref _entries[i];
 937                oldEntry.HashCode = _comparer.GetHashCode(oldEntry.Key) & 0x7FFFFFFF;
 938                int newIndex = oldEntry.HashCode & newMask;
 939                int step = 1;
 940                while (newEntries[newIndex].IsUsed)
 941                {
 942                    newIndex = (newIndex + step * step) & newMask; // Quadratic probing
 943                    step++;
 944                }
 945                newEntries[newIndex] = _entries[i];
 946                if (newIndex > lastIndex) lastIndex = newIndex;
 947            }
 948        }
 949
 950        _lastIndex = lastIndex;
 951
 952        _entryMask = newMask;
 953        _entries = newEntries;
 954
 955        _version++;
 956    }
 957
 958    /// <summary>
 959    /// Finds the arrayIndex of the entry with the specified key.
 960    /// </summary>
 961    /// <param name="key">The key to locate in the dictionary.</param>
 962    /// <returns>The arrayIndex of the entry if found; otherwise, -1.</returns>
 963    /// <exception cref="ArgumentNullException">The key is null.</exception>
 964    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 965    protected int FindEntry(TKey key)
 966    {
 967        if (key == null) return -1;
 968
 969        int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
 970        int entryIndex = hashCode & _entryMask;
 971
 972        int step = 0;
 973        while ((uint)step <= (uint)_lastIndex)
 974        {
 975            ref Entry entry = ref _entries[entryIndex];
 976            // Stop probing if an unused entry is found (not deleted)
 977            if (!entry.IsUsed && entry.HashCode != -1)
 978                return -1;
 979            if (entry.IsUsed && entry.HashCode == hashCode && _comparer.Equals(entry.Key, key))
 980                return entryIndex; // Match found
 981
 982            // Perform quadratic probing to see if maybe the entry was shifted.
 983            step++;
 984            entryIndex = (entryIndex + step * step) & _entryMask;
 985        }
 986        return -1; // Item not found, full loop completed
 987    }
 988
 989    #endregion
 990
 991    #region IEnumerable Implementation
 992
 993    /// <inheritdoc cref="IEnumerable.GetEnumerator()"/>
 994    public SwiftDictionaryEnumerator GetEnumerator() => new(this);
 995    IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() => GetEnumerator();
 996    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 997    IDictionaryEnumerator IDictionary.GetEnumerator() => new SwiftDictionaryEnumerator(this, true);
 998
 999    /// <summary>
 1000    /// Provides an efficient enumerator for iterating over the key-value pairs in the SwiftDictionary, enabling smooth 
 1001    /// </summary>
 1002    [Serializable]
 1003    public struct SwiftDictionaryEnumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IEnumerator, IDictionaryEnumerato
 1004    {
 1005        private readonly SwiftDictionary<TKey, TValue> _dictionary;
 1006        private readonly Entry[] _entries;
 1007        private readonly uint _version;
 1008        private readonly bool _returnEntry;
 1009        private int _index;
 1010        private KeyValuePair<TKey, TValue> _current;
 1011
 1012        internal SwiftDictionaryEnumerator(SwiftDictionary<TKey, TValue> dictionary, bool returnEntry = false)
 1013        {
 1014            _dictionary = dictionary;
 1015            _entries = dictionary._entries;
 1016            _version = dictionary._version;
 1017            _returnEntry = returnEntry;
 1018            _index = -1;
 1019            _current = default;
 1020        }
 1021
 1022        object IDictionaryEnumerator.Key
 1023        {
 1024            get
 1025            {
 1026                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 1027                return _current.Key;
 1028            }
 1029        }
 1030
 1031        object IDictionaryEnumerator.Value
 1032        {
 1033            get
 1034            {
 1035                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 1036                return _current.Value!;
 1037            }
 1038        }
 1039
 1040        DictionaryEntry IDictionaryEnumerator.Entry
 1041        {
 1042            get
 1043            {
 1044                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 1045                return new DictionaryEntry(_current.Key, _current.Value);
 1046            }
 1047        }
 1048
 1049        /// <inheritdoc/>
 1050        public KeyValuePair<TKey, TValue> Current => _current;
 1051
 1052        object IEnumerator.Current
 1053        {
 1054            get
 1055            {
 1056                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 1057                return _returnEntry
 1058                    ? new DictionaryEntry(_current.Key, _current.Value)
 1059                    : new KeyValuePair<TKey, TValue>(_current.Key, _current.Value);
 1060            }
 1061        }
 1062
 1063        /// <inheritdoc/>
 1064        public bool MoveNext()
 1065        {
 1066            SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of enum
 1067
 1068            while (++_index <= (uint)_dictionary._lastIndex)
 1069            {
 1070                if (_entries[_index].IsUsed)
 1071                {
 1072                    _current = new KeyValuePair<TKey, TValue>(_entries[_index].Key, _entries[_index].Value);
 1073                    return true;
 1074                }
 1075            }
 1076
 1077            _current = default;
 1078            return false;
 1079        }
 1080
 1081        /// <inheritdoc/>
 1082        public void Reset()
 1083        {
 1084            SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of enum
 1085
 1086            _index = -1;
 1087            _current = default;
 1088        }
 1089
 1090        /// <inheritdoc/>
 1091        public void Dispose() => _index = -1;
 1092    }
 1093
 1094    #endregion
 1095
 1096    #region Key & Value Collections
 1097
 1098    /// <summary>
 1099    /// Provides a dynamic, read-only collection of all keys in the dictionary, supporting enumeration and copy operatio
 1100    /// </summary>
 1101    [Serializable]
 1102    public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>, IEnumerable<TKey>, IE
 1103    {
 1104        private readonly SwiftDictionary<TKey, TValue> _dictionary;
 1105        private readonly Entry[] _entries;
 1106
 1107        /// <summary>
 1108        /// Initializes a new instance of the KeyCollection class that reflects the keys in the specified dictionary.
 1109        /// </summary>
 1110        /// <param name="dictionary">The dictionary whose keys are reflected in the new KeyCollection.</param>
 1111        /// <exception cref="ArgumentNullException">The dictionary is null.</exception>
 1112        public KeyCollection(SwiftDictionary<TKey, TValue> dictionary)
 1113        {
 1114            SwiftThrowHelper.ThrowIfNull(dictionary, nameof(dictionary));
 1115            _dictionary = dictionary;
 1116            _entries = dictionary._entries;
 1117        }
 1118
 1119        /// <inheritdoc/>
 1120        public int Count => _dictionary._count;
 1121
 1122        bool ICollection.IsSynchronized => false;
 1123
 1124        object ICollection.SyncRoot => ((ICollection)_dictionary).SyncRoot;
 1125
 1126        bool ICollection<TKey>.IsReadOnly => true;
 1127
 1128        void ICollection<TKey>.Add(TKey item) => throw new NotSupportedException();
 1129
 1130        void ICollection<TKey>.Clear() => throw new NotSupportedException();
 1131
 1132        bool ICollection<TKey>.Contains(TKey item) => _dictionary.ContainsKey(item);
 1133
 1134        bool ICollection<TKey>.Remove(TKey item) => false;
 1135
 1136        /// <inheritdoc/>
 1137        public void CopyTo(TKey[] array, int arrayIndex)
 1138        {
 1139            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 1140            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 1141            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1142
 1143            for (int i = 0, j = arrayIndex; i < _entries.Length; i++)
 1144            {
 1145                if (_entries[i].IsUsed)
 1146                    array[j++] = _entries[i].Key;
 1147            }
 1148        }
 1149
 1150        void ICollection.CopyTo(Array array, int arrayIndex)
 1151        {
 1152            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 1153            SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Multidimensional array not supported");
 1154            SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Non-zero lower bound");
 1155            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 1156            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1157
 1158            if (array is TKey[] keysArray)
 1159                CopyTo(keysArray, arrayIndex);
 1160            else if (array is object[] objects)
 1161            {
 1162                try
 1163                {
 1164                    for (int i = 0, j = arrayIndex; i < _entries.Length; i++)
 1165                    {
 1166                        if (_entries[i].IsUsed)
 1167                            objects[j++] = _entries[i].Key;
 1168                    }
 1169                }
 1170                catch (ArrayTypeMismatchException)
 1171                {
 1172                    throw new ArgumentException("Invalid array type", nameof(array));
 1173                }
 1174            }
 1175            else
 1176            {
 1177                throw new ArgumentException("Invalid array type", nameof(array));
 1178            }
 1179        }
 1180
 1181        /// <summary>
 1182        /// Returns an enumerator that iterates through the keys in the collection.
 1183        /// </summary>
 1184        /// <returns>An enumerator for the keys in the collection.</returns>
 1185        public KeyCollectionEnumerator GetEnumerator() => new(_dictionary);
 1186        IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator() => GetEnumerator();
 1187        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 1188
 1189        /// <summary>
 1190        /// Enumerates the keys of a <see cref="SwiftDictionary{TKey, TValue}"/> collection.
 1191        /// </summary>
 1192        /// <remarks>
 1193        /// The enumerator provides read-only, forward-only iteration over the keys in the dictionary.
 1194        /// The enumerator is invalidated if the dictionary is modified after the enumerator is created.
 1195        /// In such cases, calling MoveNext or Reset will throw an InvalidOperationException.
 1196        /// </remarks>
 1197        [Serializable]
 1198        public struct KeyCollectionEnumerator : IEnumerator<TKey>, IEnumerator, IDisposable
 1199        {
 1200            private readonly SwiftDictionary<TKey, TValue> _dictionary;
 1201            private readonly Entry[] _entries;
 1202            private readonly uint _version;
 1203            private int _index;
 1204            private TKey _currentKey;
 1205
 1206            internal KeyCollectionEnumerator(SwiftDictionary<TKey, TValue> dictionary)
 1207            {
 1208                _dictionary = dictionary;
 1209                _entries = dictionary._entries;
 1210                _version = dictionary._version;
 1211                _index = -1;
 1212                _currentKey = default!;
 1213            }
 1214
 1215            /// <inheritdoc/>
 1216            public TKey Current => _currentKey;
 1217
 1218            object IEnumerator.Current
 1219            {
 1220                get
 1221                {
 1222                    SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is position
 1223                    return _currentKey;
 1224                }
 1225            }
 1226
 1227            /// <inheritdoc/>
 1228            public bool MoveNext()
 1229            {
 1230                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1231
 1232                while (++_index <= (uint)_dictionary._lastIndex)
 1233                {
 1234                    if (_entries[_index].IsUsed)
 1235                    {
 1236                        _currentKey = _entries[_index].Key;
 1237                        return true;
 1238                    }
 1239                }
 1240
 1241                _currentKey = default!;
 1242                return false;
 1243            }
 1244
 1245            /// <inheritdoc/>
 1246            public void Reset()
 1247            {
 1248                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1249
 1250                _index = -1;
 1251                _currentKey = default!;
 1252            }
 1253
 1254            /// <inheritdoc/>
 1255            public void Dispose() => _index = -1;
 1256        }
 1257    }
 1258
 1259    /// <summary>
 1260    /// Offers a dynamic, read-only collection of all values in the dictionary, supporting enumeration and copy operatio
 1261    /// </summary>
 1262    [Serializable]
 1263    public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>, IEnumerable<TVa
 1264    {
 1265        private readonly SwiftDictionary<TKey, TValue> _dictionary;
 1266        private readonly Entry[] _entries;
 1267
 1268        /// <summary>
 1269        /// Initializes a new instance of the ValueCollection class that reflects the values in the specified dictionary
 1270        /// </summary>
 1271        /// <param name="dictionary">The dictionary whose values are reflected in the new ValueCollection.</param>
 1272        /// <exception cref="ArgumentNullException">The dictionary is null.</exception>
 1273        public ValueCollection(SwiftDictionary<TKey, TValue> dictionary)
 1274        {
 1275            SwiftThrowHelper.ThrowIfNull(dictionary, nameof(dictionary));
 1276            _dictionary = dictionary;
 1277            _entries = dictionary._entries;
 1278        }
 1279
 1280        /// <inheritdoc/>
 1281        public int Count => _dictionary._count;
 1282
 1283        bool ICollection<TValue>.IsReadOnly => true;
 1284
 1285        bool ICollection.IsSynchronized => false;
 1286
 1287        object ICollection.SyncRoot => ((ICollection)_dictionary).SyncRoot;
 1288
 1289        void ICollection<TValue>.Add(TValue item) => throw new NotSupportedException();
 1290
 1291        void ICollection<TValue>.Clear() => throw new NotSupportedException();
 1292
 1293        bool ICollection<TValue>.Contains(TValue item)
 1294        {
 1295            for (uint i = 0; i <= (uint)_dictionary._lastIndex; i++)
 1296            {
 1297                if (_entries[i].IsUsed && EqualityComparer<TValue>.Default.Equals(_entries[i].Value, item))
 1298                    return true;
 1299            }
 1300            return false;
 1301        }
 1302
 1303        bool ICollection<TValue>.Remove(TValue item) => false;
 1304
 1305        /// <inheritdoc/>
 1306        public void CopyTo(TValue[] array, int arrayIndex)
 1307        {
 1308            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 1309            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 1310            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1311
 1312            for (int i = 0, j = arrayIndex; i <= _dictionary._lastIndex; i++)
 1313            {
 1314                if (_dictionary._entries[i].IsUsed)
 1315                    array[j++] = _entries[i].Value;
 1316            }
 1317        }
 1318
 1319        void ICollection.CopyTo(Array array, int arrayIndex)
 1320        {
 1321            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 1322            SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Multidimensional array not supported");
 1323            SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Non-zero lower bound");
 1324            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 1325            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1326
 1327            if (array is TValue[] valuesArray)
 1328                CopyTo(valuesArray, arrayIndex);
 1329            else if (array is object[] objects)
 1330            {
 1331                try
 1332                {
 1333                    for (int i = 0, j = arrayIndex; i <= _dictionary._lastIndex; i++)
 1334                        if (_entries[i].IsUsed)
 1335                            objects[j++] = _entries[i].Value!;
 1336                }
 1337                catch (ArrayTypeMismatchException)
 1338                {
 1339                    throw new ArgumentException("Invalid array type", nameof(array));
 1340                }
 1341            }
 1342            else throw new ArgumentException("Invalid array type", nameof(array));
 1343        }
 1344
 1345        /// <summary>
 1346        /// Returns an enumerator that iterates through the values in the collection.
 1347        /// </summary>
 1348        /// <returns>An enumerator for the values in the collection.</returns>
 1349        public ValueCollectionEnumerator GetEnumerator() => new(_dictionary);
 1350        IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() => GetEnumerator();
 1351        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 1352
 1353        /// <summary>
 1354        /// Enumerates the values in a SwiftDictionary collection.
 1355        /// </summary>
 1356        /// <remarks>
 1357        /// The enumerator is invalidated if the collection is modified after the enumerator is created.
 1358        /// Enumerators are typically used in a foreach statement to iterate through the collection values.
 1359        /// </remarks>
 1360        [Serializable]
 1361        public struct ValueCollectionEnumerator : IEnumerator<TValue>, IEnumerator, IDisposable
 1362        {
 1363            private readonly SwiftDictionary<TKey, TValue> _dictionary;
 1364            private readonly Entry[] _entries;
 1365            private readonly uint _version;
 1366            private int _index;
 1367            private TValue _currentValue;
 1368
 1369            internal ValueCollectionEnumerator(SwiftDictionary<TKey, TValue> dictionary)
 1370            {
 1371                _dictionary = dictionary;
 1372                _entries = dictionary._entries;
 1373                _version = dictionary._version;
 1374                _index = -1;
 1375                _currentValue = default!;
 1376            }
 1377
 1378            /// <inheritdoc/>
 1379            public TValue Current => _currentValue;
 1380
 1381            object IEnumerator.Current
 1382            {
 1383                get
 1384                {
 1385                    SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is position
 1386                    return _currentValue!;
 1387                }
 1388            }
 1389
 1390            /// <inheritdoc/>
 1391            public bool MoveNext()
 1392            {
 1393                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1394
 1395                while (++_index <= (uint)_dictionary._lastIndex)
 1396                {
 1397                    if (_entries[_index].IsUsed)
 1398                    {
 1399                        _currentValue = _entries[_index].Value;
 1400                        return true;
 1401                    }
 1402                }
 1403
 1404                _currentValue = default!;
 1405                return false;
 1406            }
 1407
 1408            /// <inheritdoc/>
 1409            public void Reset()
 1410            {
 1411                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1412
 1413                _index = -1;
 1414                _currentValue = default!;
 1415            }
 1416
 1417            /// <inheritdoc/>
 1418            public void Dispose() => _index = -1;
 1419        }
 1420    }
 1421
 1422    #endregion
 1423}