< Summary

Information
Class: SwiftCollections.MemberNotNullAttribute
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftDictionary.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 1414
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%
get_Members()100%11100%

File(s)

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

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