< Summary

Information
Class: SwiftCollections.SwiftDictionary<T1, T2>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftDictionary.cs
Line coverage
100%
Covered lines: 484
Uncovered lines: 0
Coverable lines: 484
Total lines: 1423
Line coverage: 100%
Branch coverage
98%
Covered branches: 203
Total branches: 206
Branch coverage: 98.5%
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%
.ctor(...)100%22100%
.ctor(...)100%44100%
.ctor(...)100%11100%
get_Count()100%11100%
get_Capacity()100%11100%
get_Comparer()100%11100%
get_Item(...)100%11100%
set_Item(...)100%22100%
System.Collections.IDictionary.get_Item(...)100%44100%
System.Collections.IDictionary.set_Item(...)100%11100%
get_Keys()100%22100%
System.Collections.IDictionary.get_Keys()50%22100%
get_Values()100%22100%
System.Collections.IDictionary.get_Values()50%22100%
System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.get_IsReadOnly()100%11100%
System.Collections.IDictionary.get_IsReadOnly()100%11100%
System.Collections.IDictionary.get_IsFixedSize()100%11100%
System.Collections.ICollection.get_IsSynchronized()100%11100%
get_SyncRoot()100%22100%
get_State()100%22100%
set_State(...)100%44100%
Add(...)100%11100%
Add(...)100%11100%
System.Collections.Generic.IDictionary<TKey,TValue>.Add(...)100%11100%
Add(...)100%11100%
InsertIfNotExist(...)100%2424100%
Remove(...)100%1616100%
System.Collections.IDictionary.Remove(...)100%22100%
Remove(...)100%44100%
Clear()100%44100%
CheckLoadThreshold()100%22100%
EnsureCapacity(...)100%22100%
Resize(...)100%88100%
TrimExcess()100%1212100%
CalculateAdaptiveResizeFactors(...)83.33%66100%
Initialize(...)100%22100%
ContainsKey(...)100%11100%
System.Collections.IDictionary.Contains(...)100%22100%
Contains(...)100%44100%
TryGetValue(...)100%22100%
CopyTo(...)100%44100%
CopyTo(...)100%44100%
CopyToDictionaryEntries(...)100%44100%
CopyToObjects(...)100%22100%
CopyToObjects(...)100%44100%
SetComparer(...)100%22100%
SwitchToRandomizedComparer()100%22100%
RehashEntries()100%88100%
FindEntry(...)100%1414100%
GetEnumerator()100%11100%
System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey,TValue>>.GetEnumerator()100%11100%
System.Collections.IEnumerable.GetEnumerator()100%11100%
System.Collections.IDictionary.GetEnumerator()100%11100%
.ctor(...)100%11100%
System.Collections.IDictionaryEnumerator.get_Key()100%11100%
System.Collections.IDictionaryEnumerator.get_Value()100%11100%
System.Collections.IDictionaryEnumerator.get_Entry()100%11100%
get_Current()100%11100%
System.Collections.IEnumerator.get_Current()100%22100%
MoveNext()100%44100%
Reset()100%11100%
Dispose()100%11100%
.ctor(...)100%11100%
get_Count()100%11100%
System.Collections.ICollection.get_IsSynchronized()100%11100%
System.Collections.ICollection.get_SyncRoot()100%11100%
System.Collections.Generic.ICollection<TKey>.get_IsReadOnly()100%11100%
System.Collections.Generic.ICollection<TKey>.Add(...)100%11100%
System.Collections.Generic.ICollection<TKey>.Clear()100%11100%
System.Collections.Generic.ICollection<TKey>.Contains(...)100%11100%
System.Collections.Generic.ICollection<TKey>.Remove(...)100%11100%
CopyTo(...)100%44100%
System.Collections.ICollection.CopyTo(...)100%88100%
GetEnumerator()100%11100%
System.Collections.Generic.IEnumerable<TKey>.GetEnumerator()100%11100%
System.Collections.IEnumerable.GetEnumerator()100%11100%
.ctor(...)100%11100%
get_Current()100%11100%
System.Collections.IEnumerator.get_Current()100%11100%
MoveNext()100%44100%
Reset()100%11100%
Dispose()100%11100%
.ctor(...)100%11100%
get_Count()100%11100%
System.Collections.Generic.ICollection<TValue>.get_IsReadOnly()100%11100%
System.Collections.ICollection.get_IsSynchronized()100%11100%
System.Collections.ICollection.get_SyncRoot()100%11100%
System.Collections.Generic.ICollection<TValue>.Add(...)100%11100%
System.Collections.Generic.ICollection<TValue>.Clear()100%11100%
System.Collections.Generic.ICollection<TValue>.Contains(...)100%66100%
System.Collections.Generic.ICollection<TValue>.Remove(...)100%11100%
CopyTo(...)100%44100%
System.Collections.ICollection.CopyTo(...)100%88100%
GetEnumerator()100%11100%
System.Collections.Generic.IEnumerable<TValue>.GetEnumerator()100%11100%
System.Collections.IEnumerable.GetEnumerator()100%11100%
.ctor(...)100%11100%
get_Current()100%11100%
System.Collections.IEnumerator.get_Current()100%11100%
MoveNext()100%44100%
Reset()100%11100%
Dispose()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>
 33    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>
 39    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>
 194183    public SwiftDictionary() : this(DefaultCapacity, null) { }
 184
 185    /// <inheritdoc cref="SwiftDictionary()"/>
 257186    public SwiftDictionary(int capacity, IEqualityComparer<TKey>? comparer = null)
 187    {
 257188        Initialize(capacity, comparer);
 189
 257190        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 257191        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 257192    }
 193
 194    /// <inheritdoc cref="SwiftDictionary()"/>
 2195    public SwiftDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey>? comparer = null)
 196    {
 2197        SwiftThrowHelper.ThrowIfNull(dictionary, nameof(dictionary));
 198
 1199        Initialize(dictionary.Count, comparer);
 200
 1201        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 1202        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 203
 6204        foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
 2205            InsertIfNotExist(kvp.Key, kvp.Value);
 1206    }
 207
 208    /// <inheritdoc cref="SwiftDictionary()"/>
 3209    public SwiftDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey>? comparer = null)
 210    {
 3211        SwiftThrowHelper.ThrowIfNull(collection, nameof(collection));
 212
 2213        int count = (collection as ICollection<KeyValuePair<TKey, TValue>>)?.Count ?? DefaultCapacity;
 214        // Dynamic padding based on collision estimation
 2215        int size = (int)(count / _LoadFactorThreshold);
 2216        Initialize(size, comparer);
 217
 2218        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 2219        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 220
 12221        foreach (KeyValuePair<TKey, TValue> kvp in collection)
 4222            InsertIfNotExist(kvp.Key, kvp.Value);
 2223    }
 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]
 11230    public SwiftDictionary(SwiftDictionaryState<TKey, TValue> state)
 231    {
 11232        State = state;
 233
 11234        SwiftThrowHelper.ThrowIfNull(_entries, nameof(_entries));
 11235        SwiftThrowHelper.ThrowIfNull(_comparer, nameof(_comparer));
 11236    }
 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]
 27247    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]
 10254    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]
 12261    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        {
 4339277            int index = FindEntry(key);
 4339278            SwiftThrowHelper.ThrowIfKeyInvalid(index, key);
 4337279            return _entries[index].Value;
 280        }
 281        set
 282        {
 9967283            int index = FindEntry(key);
 9967284            if (index >= 0)
 6512285                _entries[index].Value = value;
 286            else
 287            {
 3455288                CheckLoadThreshold();
 3455289                InsertIfNotExist(key, value);
 290            }
 3455291        }
 292    }
 293
 294    /// <inheritdoc/>
 295    [JsonIgnore]
 296    [MemoryPackIgnore]
 297    object? IDictionary.this[object obj]
 298    {
 299        get
 300        {
 19301            SwiftThrowHelper.ThrowIfNull(obj, nameof(obj));
 302
 18303            if (obj is TKey key)
 304            {
 17305                int index = FindEntry(key);
 33306                if (index >= 0) return _entries[index].Value;
 307            }
 2308            return null;
 309        }
 310        set
 311        {
 5312            SwiftThrowHelper.ThrowIfNullAndNullsAreIllegal(value, default(TValue));
 313            try
 314            {
 5315                TKey tempKey = (TKey)obj;
 316                try
 317                {
 3318                    this[tempKey] = (TValue)value!;
 1319                }
 2320                catch (InvalidCastException)
 321                {
 2322                    throw new ArgumentException($"Value {value} does not match expected {typeof(TValue)}");
 323                }
 1324            }
 2325            catch (InvalidCastException)
 326            {
 2327                throw new ArgumentException($"Key {obj} does not match expected {typeof(TKey)}");
 328            }
 1329        }
 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]
 11342    public ICollection<TKey> Keys => _keyCollection ??= new KeyCollection(this);
 343
 344    [JsonIgnore]
 345    [MemoryPackIgnore]
 4346    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]
 12358    public ICollection<TValue> Values => _valueCollection ??= new ValueCollection(this);
 359
 360    [JsonIgnore]
 361    [MemoryPackIgnore]
 1362    ICollection IDictionary.Values => _valueCollection ??= new ValueCollection(this);
 363
 364    [JsonIgnore]
 365    [MemoryPackIgnore]
 1366    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
 367
 368    [JsonIgnore]
 1369    [MemoryPackIgnore] bool IDictionary.IsReadOnly => false;
 1370    bool IDictionary.IsFixedSize => false;
 371
 372    [JsonIgnore]
 373    [MemoryPackIgnore]
 1374    bool ICollection.IsSynchronized => false;
 375
 376    /// <inheritdoc/>
 377    [JsonIgnore]
 378    [MemoryPackIgnore]
 3379    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        {
 15395            if (_count == 0)
 2396                return new SwiftDictionaryState<TKey, TValue>(Array.Empty<KeyValuePair<TKey, TValue>>());
 397
 13398            var items = new KeyValuePair<TKey, TValue>[_count];
 13399            CopyTo(items, 0);
 400
 13401            return new SwiftDictionaryState<TKey, TValue>(items);
 402        }
 403        internal set
 404        {
 17405            SwiftThrowHelper.ThrowIfNull(value.Items, nameof(value.Items));
 406
 17407            var items = value.Items;
 17408            int count = items.Length;
 409
 17410            if (count == 0)
 411            {
 3412                Initialize(DefaultCapacity);
 3413                _count = 0;
 3414                _version = 0;
 3415                return;
 416            }
 417
 14418            int size = (int)(count / _LoadFactorThreshold);
 14419            Initialize(size);
 420
 108421            foreach (var kvp in items)
 40422                InsertIfNotExist(kvp.Key, kvp.Value);
 423
 14424            _version = 0;
 14425        }
 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    {
 21707444        CheckLoadThreshold();
 21707445        return InsertIfNotExist(key, value);
 446    }
 447
 448    /// <inheritdoc/>
 1449    public void Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
 450
 1451    void IDictionary<TKey, TValue>.Add(TKey key, TValue value) => Add(key, value);
 452
 453    /// <inheritdoc/>
 454    public void Add(object key, object? value)
 455    {
 6456        SwiftThrowHelper.ThrowIfNullAndNullsAreIllegal(value, default(TValue));
 457
 458        try
 459        {
 6460            TKey tempKey = (TKey)key;
 461            try
 462            {
 4463                Add(tempKey, (TValue)value!);
 1464            }
 2465            catch (InvalidCastException)
 466            {
 2467                throw new ArgumentException($"Value {value} does not match expected {typeof(TValue)}");
 468            }
 1469        }
 2470        catch (InvalidCastException)
 471        {
 2472            throw new ArgumentException($"Key {key} does not match expected {typeof(TKey)}");
 473        }
 1474    }
 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    {
 25212489        SwiftThrowHelper.ThrowIfNullGeneric(key, nameof(key));
 490
 25210491        int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
 25210492        int entryIndex = hashCode & _entryMask;
 493
 25210494        int firstDeletedIndex = -1;
 25210495        int step = 1;
 25210496        int probeLimit = _entries.Length;
 45135497        while ((uint)step <= (uint)probeLimit)
 498        {
 45132499            ref Entry entry = ref _entries[entryIndex];
 45132500            if (entry.IsUsed)
 501            {
 19961502                if (entry.HashCode == hashCode && _comparer.Equals(entry.Key, key))
 44503                    return false; // Item already exists
 504            }
 25171505            else if (entry.HashCode == -1)
 506            {
 14507                if (firstDeletedIndex < 0) firstDeletedIndex = entryIndex;
 508            }
 509            else
 510            {
 511                break;
 512            }
 513
 19925514            entryIndex = (entryIndex + step * step) & _entryMask; // Quadratic probing
 19925515            step++;
 516        }
 517
 25166518        if (firstDeletedIndex >= 0)
 5519            entryIndex = firstDeletedIndex;
 25161520        else if ((uint)step > (uint)probeLimit)
 521        {
 3522            Resize(_entries.Length * _adaptiveResizeFactor);
 3523            return InsertIfNotExist(key, value);
 524        }
 525
 41757526        if ((uint)entryIndex > (uint)_lastIndex) _lastIndex = entryIndex;
 527
 25163528        _entries[entryIndex].HashCode = hashCode;
 25163529        _entries[entryIndex].Key = key;
 25163530        _entries[entryIndex].Value = value;
 25163531        _entries[entryIndex].IsUsed = true;
 25163532        _count++;
 25163533        _version++;
 534
 25163535        if ((uint)step > (uint)_maxStepCount)
 536        {
 1588537            _maxStepCount = step;
 1588538            if (_comparer is not IRandomedEqualityComparer && _maxStepCount > 100)
 23539                SwitchToRandomizedComparer();  // Attempt to recompute hash code with potential randomization for better
 540        }
 541
 542
 25163543        return true;
 544    }
 545
 546    /// <inheritdoc/>
 547    public virtual bool Remove(TKey key)
 548    {
 6080549        if (key == null) return false;
 550
 6078551        int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
 6078552        int entryIndex = hashCode & _entryMask;
 553
 6078554        int step = 0;
 6507555        while ((uint)step <= (uint)_lastIndex)
 556        {
 6506557            ref Entry entry = ref _entries[entryIndex];
 558            // Stop probing if an unused entry is found (not deleted)
 6506559            if (!entry.IsUsed && entry.HashCode != -1)
 1560                return false;
 6505561            if (entry.IsUsed && entry.HashCode == hashCode && _comparer.Equals(entry.Key, key))
 562            {
 563                // Mark entry as deleted
 6076564                entry.IsUsed = false;
 6076565                entry.Key = default!;
 6076566                entry.Value = default!;
 6076567                entry.HashCode = -1;
 6076568                _count--;
 6087569                if ((uint)_count == 0) _lastIndex = 0;
 6076570                _version++;
 6076571                return true;
 572            }
 573
 574            // Move to the next entry using linear probing
 429575            step++;
 429576            entryIndex = (entryIndex + step * step) & _entryMask;
 577        }
 1578        return false; // Item not found after full loop
 579    }
 580
 581    void IDictionary.Remove(object obj)
 582    {
 2583        SwiftThrowHelper.ThrowIfNull(obj, nameof(obj));
 3584        if (obj is TKey key) Remove(key);
 2585    }
 586
 587    /// <inheritdoc/>
 588    public bool Remove(KeyValuePair<TKey, TValue> item)
 589    {
 3590        int index = FindEntry(item.Key);
 3591        if (index >= 0 && EqualityComparer<TValue>.Default.Equals(_entries[index].Value, item.Value))
 592        {
 1593            Remove(item.Key);
 1594            return true;
 595        }
 2596        return false;
 597    }
 598
 599    /// <inheritdoc/>
 600    public virtual void Clear()
 601    {
 1063602        if ((uint)_count == 0) return;
 603
 6608604        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.
 2245608            _entries[i].HashCode = 0;
 2245609            _entries[i].Key = default!;
 2245610            _entries[i].Value = default!;
 2245611            _entries[i].IsUsed = false;
 612        }
 613
 1059614        _count = 0;
 1059615        _lastIndex = 0;
 1059616        _maxStepCount = 0;
 1059617        _movingFillRate = 0;
 1059618        _adaptiveResizeFactor = 4;
 619
 1059620        _version++;
 1059621    }
 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    {
 25164633        if ((uint)_count >= _nextResizeCount)
 62634            Resize(_entries.Length * _adaptiveResizeFactor);
 25164635    }
 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    {
 6646        capacity = SwiftHashTools.NextPowerOfTwo(capacity);  // Capacity must be a power of 2 for proper masking
 6647        if (capacity > _entries.Length)
 3648            Resize(capacity);
 6649    }
 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    {
 68657        Entry[] newEntries = new Entry[newSize];
 68658        int newMask = newSize - 1;
 659
 68660        int lastIndex = 0;
 35560661        for (uint i = 0; i <= (uint)_lastIndex; i++)
 662        {
 17712663            if (_entries[i].IsUsed) // Only rehash valid entries
 664            {
 16667665                ref Entry oldEntry = ref _entries[i];
 16667666                int newIndex = oldEntry.HashCode & newMask;
 667                // If current entry not available, perform Quadratic probing to find the next available entry
 16667668                int step = 1;
 17302669                while (newEntries[newIndex].IsUsed)
 670                {
 635671                    newIndex = (newIndex + step * step) & newMask;
 635672                    step++;
 673                }
 16667674                newEntries[newIndex] = oldEntry;
 28876675                if (newIndex > lastIndex) lastIndex = newIndex;
 676            }
 677        }
 678
 68679        _lastIndex = lastIndex;
 680
 68681        CalculateAdaptiveResizeFactors(newSize);
 682
 68683        _entries = newEntries;
 68684        _entryMask = newMask;
 685
 68686        _version++;
 68687    }
 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    {
 3695        int newSize = _count <= DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(_count);
 4696        if (newSize >= _entries.Length) return;
 697
 2698        Entry[] newEntries = new Entry[newSize];
 2699        int newMask = newSize - 1;
 700
 2701        int lastIndex = 0;
 40702        for (int i = 0; i <= (uint)_lastIndex; i++)
 703        {
 18704            if (_entries[i].IsUsed)
 705            {
 15706                ref Entry oldEntry = ref _entries[i];
 15707                int newIndex = oldEntry.HashCode & newMask;
 708                // If current entry not available, perform quadratic probing to find the next available entry
 15709                int step = 1;
 18710                while (newEntries[newIndex].IsUsed)
 711                {
 3712                    newIndex = (newIndex + step * step) & newMask;
 3713                    step++;
 714                }
 15715                newEntries[newIndex] = oldEntry;
 28716                if (newIndex > lastIndex) lastIndex = newIndex;
 717            }
 718        }
 719
 2720        _lastIndex = lastIndex;
 721
 2722        CalculateAdaptiveResizeFactors(newSize);
 723
 2724        _entryMask = newMask;
 2725        _entries = newEntries;
 726
 2727        _version++;
 2728    }
 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
 70738        double currentFillRate = (double)_count / newSize;
 70739        _movingFillRate = _movingFillRate == 0 ? currentFillRate : (_movingFillRate * 0.7 + currentFillRate * 0.3);
 740
 70741        if (_movingFillRate > 0.3f)
 2742            _adaptiveResizeFactor = 2; // Growth stabilizing
 68743        else if (_movingFillRate < 0.28f)
 68744            _adaptiveResizeFactor = 4; // Rapid growth
 745
 746        // Reset the resize threshold based on the new size
 70747        _nextResizeCount = (uint)(newSize * _LoadFactorThreshold);
 70748    }
 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    {
 277763        _comparer = SwiftHashTools.GetDefaultEqualityComparer(comparer);
 764
 277765        int size = capacity < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(capacity);
 277766        _entries = new Entry[size];
 277767        _entryMask = size - 1;
 768
 277769        _nextResizeCount = (uint)(size * _LoadFactorThreshold);
 277770        _adaptiveResizeFactor = 4; // start agressive
 277771        _movingFillRate = 0.0;
 277772    }
 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)]
 19320780    public bool ContainsKey(TKey key) => FindEntry(key) >= 0;
 781
 782    bool IDictionary.Contains(object obj)
 783    {
 5784        SwiftThrowHelper.ThrowIfNull(obj, nameof(obj));
 785
 9786        if (obj is TKey key) return ContainsKey(key);
 1787        return false;
 788    }
 789
 790    /// <inheritdoc/>
 791    public bool Contains(KeyValuePair<TKey, TValue> item)
 792    {
 2793        int index = FindEntry(item.Key);
 2794        if (index >= 0 && EqualityComparer<TValue>.Default.Equals(_entries[index].Value, item.Value))
 1795            return true;
 1796        return false;
 797    }
 798
 799    /// <inheritdoc/>
 800    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 801    public bool TryGetValue(TKey key, out TValue value)
 802    {
 8142803        int index = FindEntry(key);
 8142804        if (index >= 0)
 805        {
 7329806            value = _entries[index].Value;
 7329807            return true;
 808        }
 813809        value = default!;
 813810        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    {
 15828        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 15829        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 15830        SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _count, nameof(array), "Insufficient space in the t
 831
 246832        for (uint i = 0; i <= (uint)_lastIndex; i++)
 833        {
 108834            if (_entries[i].IsUsed)
 42835                array[arrayIndex++] = new KeyValuePair<TKey, TValue>(_entries[i].Key, _entries[i].Value);
 836        }
 15837    }
 838
 839    /// <inheritdoc/>
 840    public void CopyTo(Array array, int arrayIndex)
 841    {
 10842        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 10843        SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Multidimensional array not supported");
 9844        SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Non-zero lower bound");
 8845        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 8846        SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _count, nameof(array), "Insufficient space in the t
 847
 7848        if (array is KeyValuePair<TKey, TValue>[] pairs)
 1849            ((ICollection<KeyValuePair<TKey, TValue>>)this).CopyTo(pairs, arrayIndex);
 6850        else if (array is DictionaryEntry[] dictEntryArray)
 2851            CopyToDictionaryEntries(dictEntryArray, arrayIndex);
 852        else
 4853            CopyToObjects(array, arrayIndex);
 2854    }
 855
 856    private void CopyToDictionaryEntries(DictionaryEntry[] array, int arrayIndex)
 857    {
 16858        for (uint i = 0; i <= (uint)_lastIndex; i++)
 859        {
 6860            if (_entries[i].IsUsed)
 4861                array[arrayIndex++] = new DictionaryEntry(_entries[i].Key, _entries[i].Value);
 862        }
 2863    }
 864
 865    private void CopyToObjects(Array array, int arrayIndex)
 866    {
 4867        if (array is not object[] objects)
 1868            throw new ArgumentException("Invalid array type", nameof(array));
 869
 870        try
 871        {
 3872            CopyToObjects(objects, arrayIndex);
 2873        }
 1874        catch (ArrayTypeMismatchException)
 875        {
 1876            throw new ArgumentException("Invalid array type", nameof(array));
 877        }
 2878    }
 879
 880    private void CopyToObjects(object[] array, int arrayIndex)
 881    {
 20882        for (uint i = 0; i <= (uint)_lastIndex; i++)
 883        {
 8884            if (_entries[i].IsUsed)
 5885                array[arrayIndex++] = new KeyValuePair<TKey, TValue>(_entries[i].Key, _entries[i].Value);
 886        }
 2887    }
 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    {
 5896        SwiftThrowHelper.ThrowIfNull(comparer, nameof(comparer));
 5897        if (ReferenceEquals(comparer, _comparer))
 1898            return;
 899
 4900        _comparer = comparer;
 4901        RehashEntries();
 4902        _maxStepCount = 0;
 4903    }
 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    {
 23912        if (SwiftHashTools.IsWellKnownEqualityComparer(_comparer))
 1913            _comparer = (IEqualityComparer<TKey>)SwiftHashTools.GetSwiftEqualityComparer(_comparer);
 22914        else return; // nothing to do here
 915
 1916        RehashEntries();
 1917        _maxStepCount = 0;
 918
 1919        _version++;
 1920    }
 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    {
 5928        Entry[] newEntries = new Entry[_entries.Length];
 5929        int newMask = newEntries.Length - 1;
 930
 5931        int lastIndex = 0;
 612932        for (uint i = 0; i <= (uint)_lastIndex; i++)
 933        {
 301934            if (_entries[i].IsUsed)
 935            {
 109936                ref Entry oldEntry = ref _entries[i];
 109937                oldEntry.HashCode = _comparer.GetHashCode(oldEntry.Key) & 0x7FFFFFFF;
 109938                int newIndex = oldEntry.HashCode & newMask;
 109939                int step = 1;
 131940                while (newEntries[newIndex].IsUsed)
 941                {
 22942                    newIndex = (newIndex + step * step) & newMask; // Quadratic probing
 22943                    step++;
 944                }
 109945                newEntries[newIndex] = _entries[i];
 130946                if (newIndex > lastIndex) lastIndex = newIndex;
 947            }
 948        }
 949
 5950        _lastIndex = lastIndex;
 951
 5952        _entryMask = newMask;
 5953        _entries = newEntries;
 954
 5955        _version++;
 5956    }
 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    {
 41793967        if (key == null) return -1;
 968
 41791969        int hashCode = _comparer.GetHashCode(key) & 0x7FFFFFFF;
 41791970        int entryIndex = hashCode & _entryMask;
 971
 41791972        int step = 0;
 54915973        while ((uint)step <= (uint)_lastIndex)
 974        {
 54902975            ref Entry entry = ref _entries[entryIndex];
 976            // Stop probing if an unused entry is found (not deleted)
 54902977            if (!entry.IsUsed && entry.HashCode != -1)
 18525978                return -1;
 36377979            if (entry.IsUsed && entry.HashCode == hashCode && _comparer.Equals(entry.Key, key))
 23253980                return entryIndex; // Match found
 981
 982            // Perform quadratic probing to see if maybe the entry was shifted.
 13124983            step++;
 13124984            entryIndex = (entryIndex + step * step) & _entryMask;
 985        }
 13986        return -1; // Item not found, full loop completed
 987    }
 988
 989    #endregion
 990
 991    #region IEnumerable Implementation
 992
 993    /// <inheritdoc cref="IEnumerable.GetEnumerator()"/>
 35994    public SwiftDictionaryEnumerator GetEnumerator() => new(this);
 24995    IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() => GetEnumerator();
 1996    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 3997    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        {
 381014            _dictionary = dictionary;
 381015            _entries = dictionary._entries;
 381016            _version = dictionary._version;
 381017            _returnEntry = returnEntry;
 381018            _index = -1;
 381019            _current = default;
 381020        }
 1021
 1022        object IDictionaryEnumerator.Key
 1023        {
 1024            get
 1025            {
 31026                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 31027                return _current.Key;
 1028            }
 1029        }
 1030
 1031        object IDictionaryEnumerator.Value
 1032        {
 1033            get
 1034            {
 11035                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 11036                return _current.Value!;
 1037            }
 1038        }
 1039
 1040        DictionaryEntry IDictionaryEnumerator.Entry
 1041        {
 1042            get
 1043            {
 21044                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 11045                return new DictionaryEntry(_current.Key, _current.Value);
 1046            }
 1047        }
 1048
 1049        /// <inheritdoc/>
 551050        public KeyValuePair<TKey, TValue> Current => _current;
 1051
 1052        object IEnumerator.Current
 1053        {
 1054            get
 1055            {
 21056                SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is positioned b
 21057                return _returnEntry
 21058                    ? new DictionaryEntry(_current.Key, _current.Value)
 21059                    : new KeyValuePair<TKey, TValue>(_current.Key, _current.Value);
 1060            }
 1061        }
 1062
 1063        /// <inheritdoc/>
 1064        public bool MoveNext()
 1065        {
 851066            SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of enum
 1067
 1691068            while (++_index <= (uint)_dictionary._lastIndex)
 1069            {
 1331070                if (_entries[_index].IsUsed)
 1071                {
 491072                    _current = new KeyValuePair<TKey, TValue>(_entries[_index].Key, _entries[_index].Value);
 491073                    return true;
 1074                }
 1075            }
 1076
 361077            _current = default;
 361078            return false;
 1079        }
 1080
 1081        /// <inheritdoc/>
 1082        public void Reset()
 1083        {
 11084            SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of enum
 1085
 11086            _index = -1;
 11087            _current = default;
 11088        }
 1089
 1090        /// <inheritdoc/>
 351091        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>
 141112        public KeyCollection(SwiftDictionary<TKey, TValue> dictionary)
 1113        {
 141114            SwiftThrowHelper.ThrowIfNull(dictionary, nameof(dictionary));
 141115            _dictionary = dictionary;
 141116            _entries = dictionary._entries;
 141117        }
 1118
 1119        /// <inheritdoc/>
 11120        public int Count => _dictionary._count;
 1121
 11122        bool ICollection.IsSynchronized => false;
 1123
 11124        object ICollection.SyncRoot => ((ICollection)_dictionary).SyncRoot;
 1125
 11126        bool ICollection<TKey>.IsReadOnly => true;
 1127
 11128        void ICollection<TKey>.Add(TKey item) => throw new NotSupportedException();
 1129
 11130        void ICollection<TKey>.Clear() => throw new NotSupportedException();
 1131
 21132        bool ICollection<TKey>.Contains(TKey item) => _dictionary.ContainsKey(item);
 1133
 11134        bool ICollection<TKey>.Remove(TKey item) => false;
 1135
 1136        /// <inheritdoc/>
 1137        public void CopyTo(TKey[] array, int arrayIndex)
 1138        {
 21139            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 21140            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 21141            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1142
 381143            for (int i = 0, j = arrayIndex; i < _entries.Length; i++)
 1144            {
 161145                if (_entries[i].IsUsed)
 41146                    array[j++] = _entries[i].Key;
 1147            }
 21148        }
 1149
 1150        void ICollection.CopyTo(Array array, int arrayIndex)
 1151        {
 51152            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 51153            SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Multidimensional array not supported");
 51154            SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Non-zero lower bound");
 51155            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 51156            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1157
 51158            if (array is TKey[] keysArray)
 11159                CopyTo(keysArray, arrayIndex);
 41160            else if (array is object[] objects)
 1161            {
 1162                try
 1163                {
 431164                    for (int i = 0, j = arrayIndex; i < _entries.Length; i++)
 1165                    {
 181166                        if (_entries[i].IsUsed)
 51167                            objects[j++] = _entries[i].Key;
 1168                    }
 21169                }
 11170                catch (ArrayTypeMismatchException)
 1171                {
 11172                    throw new ArgumentException("Invalid array type", nameof(array));
 1173                }
 1174            }
 1175            else
 1176            {
 11177                throw new ArgumentException("Invalid array type", nameof(array));
 1178            }
 21179        }
 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>
 91185        public KeyCollectionEnumerator GetEnumerator() => new(_dictionary);
 71186        IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator() => GetEnumerator();
 21187        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            {
 91208                _dictionary = dictionary;
 91209                _entries = dictionary._entries;
 91210                _version = dictionary._version;
 91211                _index = -1;
 91212                _currentKey = default!;
 91213            }
 1214
 1215            /// <inheritdoc/>
 241216            public TKey Current => _currentKey;
 1217
 1218            object IEnumerator.Current
 1219            {
 1220                get
 1221                {
 11222                    SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is position
 11223                    return _currentKey;
 1224                }
 1225            }
 1226
 1227            /// <inheritdoc/>
 1228            public bool MoveNext()
 1229            {
 251230                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1231
 491232                while (++_index <= (uint)_dictionary._lastIndex)
 1233                {
 451234                    if (_entries[_index].IsUsed)
 1235                    {
 201236                        _currentKey = _entries[_index].Key;
 201237                        return true;
 1238                    }
 1239                }
 1240
 41241                _currentKey = default!;
 41242                return false;
 1243            }
 1244
 1245            /// <inheritdoc/>
 1246            public void Reset()
 1247            {
 11248                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1249
 11250                _index = -1;
 11251                _currentKey = default!;
 11252            }
 1253
 1254            /// <inheritdoc/>
 71255            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>
 111273        public ValueCollection(SwiftDictionary<TKey, TValue> dictionary)
 1274        {
 111275            SwiftThrowHelper.ThrowIfNull(dictionary, nameof(dictionary));
 111276            _dictionary = dictionary;
 111277            _entries = dictionary._entries;
 111278        }
 1279
 1280        /// <inheritdoc/>
 11281        public int Count => _dictionary._count;
 1282
 11283        bool ICollection<TValue>.IsReadOnly => true;
 1284
 11285        bool ICollection.IsSynchronized => false;
 1286
 11287        object ICollection.SyncRoot => ((ICollection)_dictionary).SyncRoot;
 1288
 11289        void ICollection<TValue>.Add(TValue item) => throw new NotSupportedException();
 1290
 11291        void ICollection<TValue>.Clear() => throw new NotSupportedException();
 1292
 1293        bool ICollection<TValue>.Contains(TValue item)
 1294        {
 201295            for (uint i = 0; i <= (uint)_dictionary._lastIndex; i++)
 1296            {
 91297                if (_entries[i].IsUsed && EqualityComparer<TValue>.Default.Equals(_entries[i].Value, item))
 21298                    return true;
 1299            }
 11300            return false;
 1301        }
 1302
 11303        bool ICollection<TValue>.Remove(TValue item) => false;
 1304
 1305        /// <inheritdoc/>
 1306        public void CopyTo(TValue[] array, int arrayIndex)
 1307        {
 21308            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 21309            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 21310            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1311
 181312            for (int i = 0, j = arrayIndex; i <= _dictionary._lastIndex; i++)
 1313            {
 61314                if (_dictionary._entries[i].IsUsed)
 41315                    array[j++] = _entries[i].Value;
 1316            }
 21317        }
 1318
 1319        void ICollection.CopyTo(Array array, int arrayIndex)
 1320        {
 51321            SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 51322            SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Multidimensional array not supported");
 51323            SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Non-zero lower bound");
 51324            SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 51325            SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _dictionary._count, nameof(array), "Insufficien
 1326
 51327            if (array is TValue[] valuesArray)
 11328                CopyTo(valuesArray, arrayIndex);
 41329            else if (array is object[] objects)
 1330            {
 1331                try
 1332                {
 231333                    for (int i = 0, j = arrayIndex; i <= _dictionary._lastIndex; i++)
 81334                        if (_entries[i].IsUsed)
 51335                            objects[j++] = _entries[i].Value!;
 21336                }
 11337                catch (ArrayTypeMismatchException)
 1338                {
 11339                    throw new ArgumentException("Invalid array type", nameof(array));
 1340                }
 1341            }
 11342            else throw new ArgumentException("Invalid array type", nameof(array));
 21343        }
 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>
 61349        public ValueCollectionEnumerator GetEnumerator() => new(_dictionary);
 41350        IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() => GetEnumerator();
 21351        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            {
 61371                _dictionary = dictionary;
 61372                _entries = dictionary._entries;
 61373                _version = dictionary._version;
 61374                _index = -1;
 61375                _currentValue = default!;
 61376            }
 1377
 1378            /// <inheritdoc/>
 131379            public TValue Current => _currentValue;
 1380
 1381            object IEnumerator.Current
 1382            {
 1383                get
 1384                {
 11385                    SwiftThrowHelper.ThrowIfTrue(_index > (uint)_dictionary._lastIndex, message: "Enumerator is position
 11386                    return _currentValue!;
 1387                }
 1388            }
 1389
 1390            /// <inheritdoc/>
 1391            public bool MoveNext()
 1392            {
 121393                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1394
 171395                while (++_index <= (uint)_dictionary._lastIndex)
 1396                {
 161397                    if (_entries[_index].IsUsed)
 1398                    {
 101399                        _currentValue = _entries[_index].Value;
 101400                        return true;
 1401                    }
 1402                }
 1403
 11404                _currentValue = default!;
 11405                return false;
 1406            }
 1407
 1408            /// <inheritdoc/>
 1409            public void Reset()
 1410            {
 11411                SwiftThrowHelper.ThrowIfTrue(_version != _dictionary._version, message: "Enumerator modified outside of 
 1412
 11413                _index = -1;
 11414                _currentValue = default!;
 11415            }
 1416
 1417            /// <inheritdoc/>
 41418            public void Dispose() => _index = -1;
 1419        }
 1420    }
 1421
 1422    #endregion
 1423}

Methods/Properties

.ctor()
.ctor(System.Int32,System.Collections.Generic.IEqualityComparer`1<TKey>)
.ctor(System.Collections.Generic.IDictionary`2<TKey,TValue>,System.Collections.Generic.IEqualityComparer`1<TKey>)
.ctor(System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<TKey,TValue>>,System.Collections.Generic.IEqualityComparer`1<TKey>)
.ctor(SwiftCollections.SwiftDictionaryState`2<TKey,TValue>)
get_Count()
get_Capacity()
get_Comparer()
get_Item(TKey)
set_Item(TKey,TValue)
System.Collections.IDictionary.get_Item(System.Object)
System.Collections.IDictionary.set_Item(System.Object,System.Object)
get_Keys()
System.Collections.IDictionary.get_Keys()
get_Values()
System.Collections.IDictionary.get_Values()
System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.get_IsReadOnly()
System.Collections.IDictionary.get_IsReadOnly()
System.Collections.IDictionary.get_IsFixedSize()
System.Collections.ICollection.get_IsSynchronized()
get_SyncRoot()
get_State()
set_State(SwiftCollections.SwiftDictionaryState`2<TKey,TValue>)
Add(TKey,TValue)
Add(System.Collections.Generic.KeyValuePair`2<TKey,TValue>)
System.Collections.Generic.IDictionary<TKey,TValue>.Add(TKey,TValue)
Add(System.Object,System.Object)
InsertIfNotExist(TKey,TValue)
Remove(TKey)
System.Collections.IDictionary.Remove(System.Object)
Remove(System.Collections.Generic.KeyValuePair`2<TKey,TValue>)
Clear()
CheckLoadThreshold()
EnsureCapacity(System.Int32)
Resize(System.Int32)
TrimExcess()
CalculateAdaptiveResizeFactors(System.Int32)
Initialize(System.Int32,System.Collections.Generic.IEqualityComparer`1<TKey>)
ContainsKey(TKey)
System.Collections.IDictionary.Contains(System.Object)
Contains(System.Collections.Generic.KeyValuePair`2<TKey,TValue>)
TryGetValue(TKey,TValue&)
CopyTo(System.Collections.Generic.KeyValuePair`2<TKey,TValue>[],System.Int32)
CopyTo(System.Array,System.Int32)
CopyToDictionaryEntries(System.Collections.DictionaryEntry[],System.Int32)
CopyToObjects(System.Array,System.Int32)
CopyToObjects(System.Object[],System.Int32)
SetComparer(System.Collections.Generic.IEqualityComparer`1<TKey>)
SwitchToRandomizedComparer()
RehashEntries()
FindEntry(TKey)
GetEnumerator()
System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey,TValue>>.GetEnumerator()
System.Collections.IEnumerable.GetEnumerator()
System.Collections.IDictionary.GetEnumerator()
.ctor(SwiftCollections.SwiftDictionary`2<TKey,TValue>,System.Boolean)
System.Collections.IDictionaryEnumerator.get_Key()
System.Collections.IDictionaryEnumerator.get_Value()
System.Collections.IDictionaryEnumerator.get_Entry()
get_Current()
System.Collections.IEnumerator.get_Current()
MoveNext()
Reset()
Dispose()
.ctor(SwiftCollections.SwiftDictionary`2<TKey,TValue>)
get_Count()
System.Collections.ICollection.get_IsSynchronized()
System.Collections.ICollection.get_SyncRoot()
System.Collections.Generic.ICollection<TKey>.get_IsReadOnly()
System.Collections.Generic.ICollection<TKey>.Add(TKey)
System.Collections.Generic.ICollection<TKey>.Clear()
System.Collections.Generic.ICollection<TKey>.Contains(TKey)
System.Collections.Generic.ICollection<TKey>.Remove(TKey)
CopyTo(TKey[],System.Int32)
System.Collections.ICollection.CopyTo(System.Array,System.Int32)
GetEnumerator()
System.Collections.Generic.IEnumerable<TKey>.GetEnumerator()
System.Collections.IEnumerable.GetEnumerator()
.ctor(SwiftCollections.SwiftDictionary`2<TKey,TValue>)
get_Current()
System.Collections.IEnumerator.get_Current()
MoveNext()
Reset()
Dispose()
.ctor(SwiftCollections.SwiftDictionary`2<TKey,TValue>)
get_Count()
System.Collections.Generic.ICollection<TValue>.get_IsReadOnly()
System.Collections.ICollection.get_IsSynchronized()
System.Collections.ICollection.get_SyncRoot()
System.Collections.Generic.ICollection<TValue>.Add(TValue)
System.Collections.Generic.ICollection<TValue>.Clear()
System.Collections.Generic.ICollection<TValue>.Contains(TValue)
System.Collections.Generic.ICollection<TValue>.Remove(TValue)
CopyTo(TValue[],System.Int32)
System.Collections.ICollection.CopyTo(System.Array,System.Int32)
GetEnumerator()
System.Collections.Generic.IEnumerable<TValue>.GetEnumerator()
System.Collections.IEnumerable.GetEnumerator()
.ctor(SwiftCollections.SwiftDictionary`2<TKey,TValue>)
get_Current()
System.Collections.IEnumerator.get_Current()
MoveNext()
Reset()
Dispose()