< Summary

Information
Class: SwiftCollections.SwiftQueue<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftQueue.cs
Line coverage
100%
Covered lines: 297
Uncovered lines: 0
Coverable lines: 297
Total lines: 856
Line coverage: 100%
Branch coverage
100%
Covered branches: 106
Total branches: 106
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor()100%11100%
.ctor(...)100%44100%
.ctor(...)100%66100%
InitializeFromKnownCountRange(...)100%66100%
.ctor(...)100%11100%
get_InnerArray()100%11100%
get_Count()100%11100%
get_Capacity()100%11100%
get_IsSynchronized()100%11100%
get_SyncRoot()100%22100%
get_IsReadOnly()100%11100%
get_Item(...)100%11100%
set_Item(...)100%11100%
get_State()100%22100%
set_State(...)100%44100%
System.Collections.Generic.ICollection<T>.Add(...)100%11100%
Enqueue(...)100%22100%
EnqueueRange(...)100%66100%
EnqueueKnownCountRange(...)100%44100%
EnqueueRange(...)100%11100%
EnqueueRange(...)100%44100%
EnsureAdditionalCapacity(...)100%11100%
Dequeue()100%22100%
TryDequeue(...)100%44100%
System.Collections.Generic.ICollection<T>.Remove(...)100%11100%
Peek()100%11100%
TryPeek(...)100%22100%
PeekTail()100%11100%
Contains(...)100%66100%
Exists(...)100%44100%
Find(...)100%44100%
Clear()100%66100%
FastClear()100%11100%
EnsureCapacity(...)100%22100%
Resize(...)100%66100%
TrimExcessCapacity()100%88100%
ToArray()100%44100%
GetSegments(...)100%44100%
CopyTo(...)100%22100%
CopyTo(...)100%22100%
CopyTo(...)100%22100%
CopyToInternal(...)100%22100%
CloneTo(...)100%22100%
GetEnumerator()100%11100%
System.Collections.Generic.IEnumerable<T>.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/SwiftQueue.cs

#LineLine coverage
 1//=======================================================================
 2// SwiftQueue.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 System;
 9using System.Collections;
 10using System.Collections.Generic;
 11using System.Runtime.CompilerServices;
 12using System.Text.Json.Serialization;
 13using Chronicler;
 14using MemoryPack;
 15using SwiftCollections.Diagnostics;
 16using SwiftCollections.Utility;
 17
 18namespace SwiftCollections;
 19
 20/// <summary>
 21/// <c>SwiftQueue&lt;T&gt;</c> is a high-performance, circular buffer-based queue designed for ultra-low-latency enqueue
 22/// <para>
 23/// It leverages power-of-two capacities and bitwise arithmetic to eliminate expensive modulo operations, enhancing perf
 24/// By managing memory efficiently with a wrap-around technique and custom capacity growth strategies, SwiftQueue minimi
 25/// Aggressive inlining and optimized exception handling further reduce overhead, making SwiftQueue outperform tradition
 26/// especially in scenarios with high-frequency additions and removals.
 27/// </para>
 28/// </summary>
 29/// <typeparam name="T">Specifies the type of elements in the queue.</typeparam>
 30[Serializable]
 31[JsonConverter(typeof(StateJsonConverterFactory))]
 32[MemoryPackable]
 33public sealed partial class SwiftQueue<T> : IStateBacked<SwiftArrayState<T>>, ISwiftCloneable<T>, IEnumerable<T>, IEnume
 34{
 35    #region Constants
 36
 37    /// <summary>
 38    /// The default initial capacity of the SwiftQueue if none is specified.
 39    /// Used to allocate a reasonable starting size to minimize resizing operations.
 40    /// </summary>
 41    public const int DefaultCapacity = 8;
 42
 243    private static readonly T[] _emptyArray = Array.Empty<T>();
 244    private static readonly bool _clearReleasedSlots = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
 45
 46    #endregion
 47
 48    #region Fields
 49
 50    /// <summary>
 51    /// The internal array that stores elements of the SwiftQueue. Resized as needed to
 52    /// accommodate additional elements. Not directly exposed outside the queue.
 53    /// </summary>
 54    private T[] _innerArray;
 55
 56    /// <summary>
 57    /// The current number of elements in the SwiftQueue. Represents the total count of
 58    /// valid elements stored in the queue, also indicating the arrayIndex of the next insertion point.
 59    /// </summary>
 60    private int _count;
 61
 62    /// <summary>
 63    /// The arrayIndex of the first element in the queue. Adjusts as elements are dequeued.
 64    /// </summary>
 65    private int _head;
 66
 67    /// <summary>
 68    /// The arrayIndex at which the next element will be enqueued, wrapping around as needed.
 69    /// </summary>
 70    private int _tail;
 71
 72    /// <summary>
 73    /// A bitmask used for efficient modulo operations, derived from the capacity of the internal array.
 74    /// </summary>
 75    private int _mask;
 76
 77    /// <summary>
 78    /// A version number used to track modifications to the SwiftQueue to help detect changes during enumeration and ens
 79    /// </summary>
 80    [NonSerialized]
 81    private uint _version;
 82
 83    /// <summary>
 84    /// An object used to synchronize access to the SwiftQueue, ensuring thread safety.
 85    /// </summary>
 86    [NonSerialized]
 87    private object? _syncRoot;
 88
 89    #endregion
 90
 91    #region Constructors
 92
 93    /// <summary>
 94    /// Initializes a new, empty instance of SwiftQueue.
 95    /// </summary>
 9296    public SwiftQueue() : this(0) { }
 97
 98    /// <summary>
 99    /// Initializes a new, empty instance of SwiftQueue with the specified initial capacity.
 100    /// </summary>
 66101    public SwiftQueue(int capacity)
 102    {
 66103        if (capacity == 0)
 104        {
 46105            _innerArray = _emptyArray;
 46106            _mask = 0;
 107        }
 108        else
 109        {
 20110            capacity = capacity < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(capacity);
 20111            _innerArray = new T[capacity];
 20112            _mask = _innerArray.Length - 1;
 113        }
 20114    }
 115
 116    /// <summary>
 117    /// Initializes a new instance of SwiftQueue that contains elements copied from the provided items.
 118    /// </summary>
 5119    public SwiftQueue(IEnumerable<T> items)
 120    {
 5121        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 5122        _innerArray = _emptyArray;
 123
 5124        if (items is ICollection<T> collection)
 125        {
 3126            InitializeFromKnownCountRange(collection, collection.Count);
 3127            return;
 128        }
 129
 2130        if (items is IReadOnlyCollection<T> readOnlyCollection)
 131        {
 1132            InitializeFromKnownCountRange(readOnlyCollection, readOnlyCollection.Count);
 1133            return;
 134        }
 135
 1136        _innerArray = new T[DefaultCapacity];
 1137        _mask = _innerArray.Length - 1;
 138
 8139        foreach (T item in items)
 3140            Enqueue(item);
 1141    }
 142
 143    private void InitializeFromKnownCountRange(IEnumerable<T> items, int count)
 144    {
 4145        if (count == 0)
 146        {
 1147            _innerArray = _emptyArray;
 1148            _mask = 0;
 149        }
 150        else
 151        {
 3152            int capacity = count < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(count);
 3153            _innerArray = new T[capacity];
 3154            _mask = _innerArray.Length - 1;
 155
 34156            foreach (T item in items)
 14157                _innerArray[_count++] = item;
 158
 3159            _tail = _count & _mask;
 160        }
 3161    }
 162
 163    ///  <summary>
 164    ///  Initializes a new instance of the <see cref="SwiftQueue{T}"/> class with the specified <see cref="SwiftArraySta
 165    ///  </summary>
 166    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 167    [MemoryPackConstructor]
 5168    public SwiftQueue(SwiftArrayState<T> state)
 169    {
 5170        State = state;
 171
 5172        SwiftThrowHelper.ThrowIfNull(_innerArray, nameof(_innerArray));
 5173    }
 174
 175    #endregion
 176
 177    #region Properties
 178
 179    /// <inheritdoc cref="_innerArray"/>
 180    [JsonIgnore]
 181    [MemoryPackIgnore]
 5182    public T[] InnerArray => _innerArray;
 183
 184    /// <inheritdoc cref="_count"/>
 185    [JsonIgnore]
 186    [MemoryPackIgnore]
 129187    public int Count => _count;
 188
 189    /// <summary>
 190    /// Gets the total number of elements the SwiftQueue can hold without resizing.
 191    /// Reflects the current allocated size of the internal array.
 192    /// </summary>
 193    [JsonIgnore]
 194    [MemoryPackIgnore]
 16195    public int Capacity => _innerArray.Length;
 196
 197    /// <inheritdoc/>
 198    [JsonIgnore]
 199    [MemoryPackIgnore]
 1200    public bool IsSynchronized => false;
 201
 202    /// <inheritdoc/>
 203    [JsonIgnore]
 204    [MemoryPackIgnore]
 3205    public object SyncRoot => _syncRoot ??= new object();
 206
 207    /// <inheritdoc/>
 208    [JsonIgnore]
 209    [MemoryPackIgnore]
 1210    public bool IsReadOnly => false;
 211
 212    /// <summary>
 213    /// Gets the element at the specified arrayIndex.
 214    /// </summary>
 215    [JsonIgnore]
 216    [MemoryPackIgnore]
 217    public T this[int index]
 218    {
 219        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 220        get
 221        {
 201222            SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 200223            return _innerArray[(_head + index) & _mask];
 224        }
 225        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 226        set
 227        {
 2228            SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 1229            _innerArray[(_head + index) & _mask] = value;
 1230        }
 231    }
 232
 233    /// <summary>
 234    /// Gets or sets the current state of the collection, including its items and order.
 235    /// </summary>
 236    /// <remarks>
 237    /// Setting this property replaces the entire contents of the collection with the items from the specified state.
 238    /// Getting this property returns a snapshot of the collection's current items and their order.
 239    /// This property is intended for serialization and deserialization scenarios.
 240    /// </remarks>
 241    [JsonInclude]
 242    [MemoryPackInclude]
 243    public SwiftArrayState<T> State
 244    {
 245        get
 246        {
 2247            var items = new T[_count];
 248
 404249            for (int i = 0; i < _count; i++)
 200250                items[i] = _innerArray[(_head + i) & _mask];
 251
 2252            return new SwiftArrayState<T>(items);
 253        }
 254        internal set
 255        {
 5256            SwiftThrowHelper.ThrowIfNull(value.Items, nameof(value.Items));
 257
 5258            int count = value.Items.Length;
 259
 5260            if (count == 0)
 261            {
 1262                _innerArray = _emptyArray;
 1263                _count = 0;
 1264                _head = 0;
 1265                _tail = 0;
 1266                _mask = 0;
 1267                _version = 0;
 1268                return;
 269            }
 270
 4271            int capacity = SwiftHashTools.NextPowerOfTwo(count <= DefaultCapacity ? DefaultCapacity : count);
 272
 4273            _innerArray = new T[capacity];
 4274            Array.Copy(value.Items, 0, _innerArray, 0, count);
 275
 4276            _count = count;
 4277            _head = 0;
 4278            _tail = count;
 4279            _mask = capacity - 1;
 280
 4281            _version = 0;
 4282        }
 283    }
 284
 285    #endregion
 286
 287    #region Collection Management
 288
 289    /// <inheritdoc/>
 1290    void ICollection<T>.Add(T item) => Enqueue(item);
 291
 292    /// <summary>
 293    /// Adds an item to the end of the queue. Automatically resizes the queue if the capacity is exceeded.
 294    /// </summary>
 295    /// <param name="item">The item to add to the queue.</param>
 296    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 297    public void Enqueue(T item)
 298    {
 318299        if ((uint)_count >= (uint)_innerArray.Length)
 34300            Resize(_innerArray.Length * 2);
 318301        _innerArray[_tail] = item;
 318302        _tail = (_tail + 1) & _mask;
 318303        _count++;
 318304        _version++;
 318305    }
 306
 307    /// <summary>
 308    /// Adds the elements of the specified collection to the end of the queue.
 309    /// </summary>
 310    /// <remarks>
 311    /// Known-count sources reserve capacity before enumeration to avoid repeated growth.
 312    /// </remarks>
 313    /// <param name="items">The collection of elements to add to the queue. Cannot be null.</param>
 314    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 315    public void EnqueueRange(IEnumerable<T> items)
 316    {
 5317        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 318
 5319        if (items is ICollection<T> collection)
 320        {
 1321            EnqueueKnownCountRange(collection, collection.Count);
 1322            return;
 323        }
 324
 4325        if (items is IReadOnlyCollection<T> readOnlyCollection)
 326        {
 2327            EnqueueKnownCountRange(readOnlyCollection, readOnlyCollection.Count);
 2328            return;
 329        }
 330
 16331        foreach (T item in items)
 6332            Enqueue(item);
 2333    }
 334
 335    private void EnqueueKnownCountRange(IEnumerable<T> items, int count)
 336    {
 3337        if (count > 0)
 338        {
 2339            EnsureAdditionalCapacity(count);
 340
 2341            int appendedCount = 0;
 28342            foreach (T item in items)
 343            {
 12344                _innerArray[_tail] = item;
 12345                _tail = (_tail + 1) & _mask;
 12346                appendedCount++;
 347            }
 348
 2349            _count += appendedCount;
 2350            _version++;
 351        }
 3352    }
 353
 354    /// <summary>
 355    /// Adds the elements of the specified array to the end of the queue in queue order.
 356    /// </summary>
 357    /// <param name="items">The array whose elements should be enqueued.</param>
 358    public void EnqueueRange(T[] items)
 359    {
 7360        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 7361        EnqueueRange(items.AsSpan());
 7362    }
 363
 364    /// <summary>
 365    /// Adds the elements of the specified span to the end of the queue in queue order.
 366    /// </summary>
 367    /// <param name="items">The span whose elements should be enqueued.</param>
 368    public void EnqueueRange(ReadOnlySpan<T> items)
 369    {
 30370        if (items.Length == 0)
 1371            return;
 372
 29373        EnsureAdditionalCapacity(items.Length);
 374
 316375        for (int i = 0; i < items.Length; i++)
 376        {
 129377            _innerArray[_tail] = items[i];
 129378            _tail = (_tail + 1) & _mask;
 379        }
 380
 29381        _count += items.Length;
 29382        _version++;
 29383    }
 384
 385    private void EnsureAdditionalCapacity(int additionalCount)
 386    {
 31387        long requiredCount = (long)_count + additionalCount;
 31388        SwiftThrowHelper.ThrowIfTrue(requiredCount > int.MaxValue, message: "The collection is too large.");
 31389        EnsureCapacity((int)requiredCount);
 31390    }
 391
 392    /// <summary>
 393    /// Removes and returns the item at the front of the queue.
 394    /// Throws an InvalidOperationException if the queue is empty.
 395    /// </summary>
 396    /// <returns>The item at the front of the queue.</returns>
 397    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 398    public T Dequeue()
 399    {
 83400        SwiftThrowHelper.ThrowIfTrue((uint)_count == 0, message: "Queue is Empty");
 82401        T item = _innerArray[_head];
 82402        if (_clearReleasedSlots)
 5403            _innerArray[_head] = default!;
 82404        _head = (_head + 1) & _mask;
 82405        _count--;
 82406        _version++;
 82407        return item;
 408    }
 409
 410    /// <summary>
 411    /// Tries to remove and return the item at the front of the queue.
 412    /// </summary>
 413    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 414    public bool TryDequeue(out T item)
 415    {
 3416        if ((uint)_count == 0)
 417        {
 1418            item = default!;
 1419            return false;
 420        }
 421
 2422        item = _innerArray[_head];
 2423        if (_clearReleasedSlots)
 1424            _innerArray[_head] = default!;
 2425        _head = (_head + 1) & _mask;
 2426        _count--;
 2427        _version++;
 2428        return true;
 429    }
 430
 1431    bool ICollection<T>.Remove(T item) => throw new NotSupportedException("Remove is not supported for SwiftQueue.");
 432
 433    /// <summary>
 434    /// Returns the item at the front of the queue without removing it.
 435    /// Throws an InvalidOperationException if the queue is empty.
 436    /// </summary>
 437    /// <returns>The item at the front of the queue.</returns>
 438    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 439    public T Peek()
 440    {
 5441        SwiftThrowHelper.ThrowIfTrue((uint)_count == 0, message: "Queue is Empty");
 3442        return _innerArray[_head];
 443    }
 444
 445    /// <summary>
 446    /// Tries to return the item at the front of the queue without removing it.
 447    /// </summary>
 448    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 449    public bool TryPeek(out T item)
 450    {
 2451        if ((uint)_count == 0)
 452        {
 1453            item = default!;
 1454            return false;
 455        }
 456
 1457        item = _innerArray[_head];
 1458        return true;
 459    }
 460
 461    /// <summary>
 462    /// Returns the item at the end of the queue without removing it.
 463    /// Throws an InvalidOperationException if the queue is empty.
 464    /// </summary>
 465    /// <returns>The item at the end of the queue.</returns>
 466    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 467    public T PeekTail()
 468    {
 4469        SwiftThrowHelper.ThrowIfTrue((uint)_count == 0, message: "Queue is Empty");
 3470        int tailIndex = (_tail - 1) & _mask;
 3471        return _innerArray[tailIndex];
 472    }
 473
 474    /// <inheritdoc/>
 475    public bool Contains(T item)
 476    {
 4477        if ((uint)_count == 0) return false;
 478
 2479        int index = _head;
 20480        for (int i = 0; i < _count; i++)
 481        {
 9482            if (Equals(_innerArray[index], item))
 1483                return true;
 484
 8485            index = (index + 1) & _mask;
 486        }
 487
 1488        return false;
 489    }
 490
 491    /// <summary>
 492    /// Determines whether the <see cref="SwiftQueue{T}"/> contains an element that matches the conditions defined by th
 493    /// </summary>
 494    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 495    /// <returns><c>true</c> if the <see cref="SwiftQueue{T}"/> contains one or more elements that match the specified p
 496    public bool Exists(Predicate<T> match)
 497    {
 3498        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 499
 2500        int index = _head;
 20501        for (int i = 0; i < _count; i++)
 502        {
 9503            if (match(_innerArray[index]))
 1504                return true;
 505
 8506            index = (index + 1) & _mask;
 507        }
 508
 1509        return false;
 510    }
 511
 512    /// <summary>
 513    /// Searches for an element that matches the conditions defined by the specified predicate, and returns the first ma
 514    /// </summary>
 515    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 516    /// <returns>The first element that matches the conditions defined by the specified predicate, if found; otherwise, 
 517    public T Find(Predicate<T> match)
 518    {
 2519        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 520
 2521        int index = _head;
 22522        for (int i = 0; i < _count; i++)
 523        {
 10524            T item = _innerArray[index];
 10525            if (match(item))
 1526                return item;
 527
 9528            index = (index + 1) & _mask;
 529        }
 530
 1531        return default!;
 532    }
 533
 534    /// <summary>
 535    /// Removes all elements from the SwiftQueue, resetting its count to zero.
 536    /// </summary>
 537    public void Clear()
 538    {
 8539        if (_count == 0) return;
 540
 4541        if (_clearReleasedSlots)
 542        {
 2543            if ((uint)_head < (uint)_tail)
 1544                Array.Clear(_innerArray, _head, _count);
 545            else
 546            {
 1547                Array.Clear(_innerArray, _head, _innerArray.Length - _head);
 1548                Array.Clear(_innerArray, 0, _tail);
 549            }
 550        }
 551
 4552        _count = 0;
 4553        _head = 0;
 4554        _tail = 0;
 4555        _version++;
 4556    }
 557
 558    /// <summary>
 559    /// Clears the SwiftQueue without releasing the reference to the stored elements.
 560    /// Use FastClear() when you want to quickly reset the list without reallocating memory.
 561    /// </summary>
 562    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 563    public void FastClear()
 564    {
 1565        _count = 0;
 1566        _tail = 0;
 1567        _head = 0;
 1568        _version++;
 1569    }
 570
 571    #endregion
 572
 573    #region Capacity Management
 574
 575    /// <summary>
 576    /// Ensures that the internal storage has at least the specified capacity, resizing if necessary.
 577    /// </summary>
 578    /// <remarks>
 579    /// If the specified capacity is not a power of two, it is rounded up to the next power of two to optimize internal 
 580    /// </remarks>
 581    /// <param name="capacity">The minimum number of elements that the internal storage should be able to hold. Must be 
 582    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 583    public void EnsureCapacity(int capacity)
 584    {
 33585        capacity = SwiftHashTools.NextPowerOfTwo(capacity);  // Capacity must be a power of 2 for proper masking
 33586        if (capacity > _innerArray.Length)
 9587            Resize(capacity);
 33588    }
 589
 590    /// <summary>
 591    /// Ensures that the capacity of the queue is sufficient to accommodate the specified number of elements.
 592    /// The capacity increases to the next power of two greater than or equal to the required minimum capacity.
 593    /// </summary>
 594    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 595    private void Resize(int newSize)
 596    {
 43597        var newArray = new T[newSize <= DefaultCapacity ? DefaultCapacity : newSize];
 43598        if ((uint)_count > 0)
 599        {
 600            // If we are not wrapped around...
 10601            if ((uint)_head < (uint)_tail)
 602            {
 603                // ...copy from head to tail into new array starting at arrayIndex 0
 1604                Array.Copy(_innerArray, _head, newArray, 0, _count);
 605            }
 606            // Else if we are wrapped around...
 607            else
 608            {
 609                // ...copy from head to end of old array to beginning of new array
 9610                Array.Copy(_innerArray, _head, newArray, 0, _innerArray.Length - _head);
 611                // ...copy from start of old array to tail into new array
 9612                Array.Copy(_innerArray, 0, newArray, _innerArray.Length - _head, _tail);
 613            }
 614        }
 615
 43616        _innerArray = newArray;
 43617        _mask = _innerArray.Length - 1;
 43618        _head = 0;
 43619        _tail = _count & _mask;
 43620        _version++;
 43621    }
 622
 623    /// <summary>
 624    /// Reduces the capacity of the SwiftQueue if the element count is significantly less than the current capacity.
 625    /// This method resizes the internal array to the next power of two greater than or equal to the current count,
 626    /// optimizing memory usage.
 627    /// </summary>
 628    public void TrimExcessCapacity()
 629    {
 5630        int newSize = _count < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(_count);
 6631        if (newSize >= _innerArray.Length) return;
 632
 4633        var newArray = new T[newSize];
 634
 4635        if ((uint)_count != 0)
 636        {
 3637            if ((uint)_head < (uint)_tail)
 638            {
 639                // No wrap-around, simple copy
 2640                Array.Copy(_innerArray, _head, newArray, 0, _count);
 641            }
 642            else
 643            {
 644                // Wrap-around, copy in two parts
 1645                Array.Copy(_innerArray, _head, newArray, 0, _innerArray.Length - _head);
 1646                Array.Copy(_innerArray, 0, newArray, _innerArray.Length - _head, _tail);
 647            }
 648        }
 649
 4650        _innerArray = newArray;
 4651        _mask = _innerArray.Length - 1;
 4652        _head = 0;
 4653        _tail = _count & _mask;
 4654        _version++;
 4655    }
 656
 657    #endregion
 658
 659    #region Utility Methods
 660
 661    /// <summary>
 662    /// Copies the elements of the SwiftQueue to a new array.
 663    /// </summary>
 664    public T[] ToArray()
 665    {
 20666        var result = new T[_count];
 21667        if ((uint)_count == 0) return result;
 19668        if ((uint)_head < (uint)_tail)
 17669            Array.Copy(_innerArray, _head, result, 0, _count);
 670        else
 671        {
 2672            int firstPartLength = _innerArray.Length - _head;
 2673            Array.Copy(_innerArray, _head, result, 0, firstPartLength);
 2674            Array.Copy(_innerArray, 0, result, firstPartLength, _tail);
 675        }
 19676        return result;
 677    }
 678
 679    /// <summary>
 680    /// Returns the current queue contents as up to two read-only spans.
 681    /// </summary>
 682    /// <param name="first">The first contiguous queue segment.</param>
 683    /// <param name="second">The wrapped tail segment, if any.</param>
 684    public void GetSegments(out ReadOnlySpan<T> first, out ReadOnlySpan<T> second)
 685    {
 5686        if ((uint)_count == 0)
 687        {
 1688            first = ReadOnlySpan<T>.Empty;
 1689            second = ReadOnlySpan<T>.Empty;
 1690            return;
 691        }
 692
 4693        if ((uint)_head < (uint)_tail)
 694        {
 2695            first = _innerArray.AsSpan(_head, _count);
 2696            second = ReadOnlySpan<T>.Empty;
 2697            return;
 698        }
 699
 2700        int firstPartLength = _innerArray.Length - _head;
 2701        first = _innerArray.AsSpan(_head, firstPartLength);
 2702        second = _innerArray.AsSpan(0, _tail);
 2703    }
 704
 705    /// <inheritdoc/>
 706    public void CopyTo(Array array, int arrayIndex)
 707    {
 6708        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 6709        SwiftThrowHelper.ThrowIfArgument((uint)array.Rank != 1, nameof(array), "Array must be single dimensional.");
 5710        SwiftThrowHelper.ThrowIfArgument((uint)array.GetLowerBound(0) != 0, nameof(array), "Array must have zero-based i
 4711        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 4712        SwiftThrowHelper.ThrowIfArgument((uint)(array.Length - arrayIndex) < _count, nameof(array), "Destination array i
 713
 4714        if ((uint)_count == 0)
 1715            return;
 716
 717        try
 718        {
 3719            CopyToInternal(array, arrayIndex);
 2720        }
 1721        catch (ArrayTypeMismatchException)
 722        {
 1723            throw new ArgumentException("Invalid array type.", nameof(array));
 724        }
 2725    }
 726
 727    /// <inheritdoc/>
 728    public void CopyTo(T[] array, int arrayIndex)
 729    {
 3730        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 3731        SwiftThrowHelper.ThrowIfArgument((uint)array.Rank != 1, nameof(array), "Array must be single dimensional.");
 3732        SwiftThrowHelper.ThrowIfArgument((uint)array.GetLowerBound(0) != 0, nameof(array), "Array must have zero-based i
 3733        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 3734        SwiftThrowHelper.ThrowIfArgument((uint)(array.Length - arrayIndex) < _count, nameof(array), "Destination array i
 735
 3736        if ((uint)_count == 0) return;
 737
 1738        CopyToInternal(array, arrayIndex);
 1739    }
 740
 741    /// <summary>
 742    /// Copies the elements of the SwiftQueue into the specified destination span.
 743    /// </summary>
 744    /// <param name="destination">The destination span.</param>
 745    public void CopyTo(Span<T> destination)
 746    {
 3747        SwiftThrowHelper.ThrowIfArgument((uint)destination.Length < _count, nameof(destination), "Destination span is no
 748
 2749        GetSegments(out ReadOnlySpan<T> first, out ReadOnlySpan<T> second);
 2750        first.CopyTo(destination);
 751
 2752        if (second.Length > 0)
 1753            second.CopyTo(destination[first.Length..]);
 2754    }
 755
 756    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 757    private void CopyToInternal(Array destination, int arrayIndex)
 758    {
 4759        if ((uint)_head < (uint)_tail)
 760        {
 2761            Array.Copy(_innerArray, _head, destination, arrayIndex, _count);
 762        }
 763        else
 764        {
 2765            int firstPartLength = _innerArray.Length - _head;
 2766            Array.Copy(_innerArray, _head, destination, arrayIndex, firstPartLength);
 2767            Array.Copy(_innerArray, 0, destination, arrayIndex + firstPartLength, _tail);
 768        }
 2769    }
 770
 771    /// <inheritdoc/>
 772    public void CloneTo(ICollection<T> output)
 773    {
 1774        SwiftThrowHelper.ThrowIfNull(output, nameof(output));
 1775        output.Clear();
 12776        foreach (var item in this)
 5777            output.Add(item);
 1778    }
 779
 780    #endregion
 781
 782    #region Enumerators
 783
 784    /// <summary>
 785    /// Returns an enumerator that iterates through the SwiftList.
 786    /// </summary>
 18787    public SwiftQueueEnumerator GetEnumerator() => new(this);
 12788    IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
 2789    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 790
 791    /// <summary>
 792    /// Enumerates the elements of a <see cref="SwiftQueue{T}"/> in the order they would be dequeued.
 793    /// </summary>
 794    public struct SwiftQueueEnumerator : IEnumerator<T>, IEnumerator, IDisposable
 795    {
 796        private readonly SwiftQueue<T> _queue;
 797        private readonly T[] _array;
 798        private readonly uint _version;
 799        private uint _index;
 800        private uint _currentIndex;
 801
 802        private T _current;
 803
 804        internal SwiftQueueEnumerator(SwiftQueue<T> queue)
 805        {
 18806            _queue = queue;
 18807            _array = queue._innerArray;
 18808            _version = queue._version;
 18809            _index = 0;
 18810            _currentIndex = (uint)queue._head - 1;
 18811            _current = default!;
 18812        }
 813
 814        /// <inheritdoc/>
 416815        public readonly T Current => _current;
 816
 817        readonly object IEnumerator.Current
 818        {
 819            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 820            get
 821            {
 3822                SwiftThrowHelper.ThrowIfTrue(_index >= (uint)_queue._count, message: "Bad enumeration");
 2823                return _current!;
 824            }
 825        }
 826
 827        /// <inheritdoc/>
 828        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 829        public bool MoveNext()
 830        {
 238831            SwiftThrowHelper.ThrowIfTrue(_version != _queue._version, message: "Collection was modified during enumerati
 832
 238833            _index++;
 254834            if (_index > (uint)_queue._count) return false;
 222835            _currentIndex++;
 223836            if (_currentIndex == _array.Length) _currentIndex = 0;
 222837            _current = _array[_currentIndex];
 222838            return true;
 839        }
 840
 841        /// <inheritdoc/>
 842        public void Reset()
 843        {
 2844            SwiftThrowHelper.ThrowIfTrue(_version != _queue._version, message: "Collection was modified during enumerati
 845
 2846            _index = 0;
 2847            _currentIndex = (uint)_queue._head - 1;
 2848            _current = default!;
 2849        }
 850
 851        /// <inheritdoc/>
 14852        public void Dispose() => _index = 0;
 853    }
 854
 855    #endregion
 856}

Methods/Properties

.cctor()
.ctor()
.ctor(System.Int32)
.ctor(System.Collections.Generic.IEnumerable`1<T>)
InitializeFromKnownCountRange(System.Collections.Generic.IEnumerable`1<T>,System.Int32)
.ctor(SwiftCollections.SwiftArrayState`1<T>)
get_InnerArray()
get_Count()
get_Capacity()
get_IsSynchronized()
get_SyncRoot()
get_IsReadOnly()
get_Item(System.Int32)
set_Item(System.Int32,T)
get_State()
set_State(SwiftCollections.SwiftArrayState`1<T>)
System.Collections.Generic.ICollection<T>.Add(T)
Enqueue(T)
EnqueueRange(System.Collections.Generic.IEnumerable`1<T>)
EnqueueKnownCountRange(System.Collections.Generic.IEnumerable`1<T>,System.Int32)
EnqueueRange(T[])
EnqueueRange(System.ReadOnlySpan`1<T>)
EnsureAdditionalCapacity(System.Int32)
Dequeue()
TryDequeue(T&)
System.Collections.Generic.ICollection<T>.Remove(T)
Peek()
TryPeek(T&)
PeekTail()
Contains(T)
Exists(System.Predicate`1<T>)
Find(System.Predicate`1<T>)
Clear()
FastClear()
EnsureCapacity(System.Int32)
Resize(System.Int32)
TrimExcessCapacity()
ToArray()
GetSegments(System.ReadOnlySpan`1<T>&,System.ReadOnlySpan`1<T>&)
CopyTo(System.Array,System.Int32)
CopyTo(T[],System.Int32)
CopyTo(System.Span`1<T>)
CopyToInternal(System.Array,System.Int32)
CloneTo(System.Collections.Generic.ICollection`1<T>)
GetEnumerator()
System.Collections.Generic.IEnumerable<T>.GetEnumerator()
System.Collections.IEnumerable.GetEnumerator()
.ctor(SwiftCollections.SwiftQueue`1<T>)
get_Current()
System.Collections.IEnumerator.get_Current()
MoveNext()
Reset()
Dispose()