< Summary

Information
Class: SwiftCollections.Pool.SwiftArrayPool<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Pool/Default/SwiftArrayPool.cs
Line coverage
100%
Covered lines: 56
Uncovered lines: 0
Coverable lines: 56
Total lines: 183
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
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%
get_Shared()100%11100%
.ctor(...)100%88100%
get_CreateFunc()100%11100%
get_ActionOnRelease()100%11100%
get_ActionOnDestroy()100%11100%
get_PoolMaxCapacity()100%11100%
Rent(...)100%11100%
Release(...)100%66100%
Clear()100%44100%
CreatePoolForSize(...)100%11100%
Dispose()100%44100%
Finalize()100%11100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Pool/Default/SwiftArrayPool.cs

#LineLine coverage
 1using System;
 2using System.Collections.Concurrent;
 3using System.Runtime.CompilerServices;
 4using System.Threading;
 5
 6namespace SwiftCollections.Pool;
 7
 8/// <summary>
 9/// A thread-safe pool designed to manage arrays of a specific size.
 10/// The pool optimizes memory usage by reusing arrays, reducing allocations and improving performance.
 11/// </summary>
 12/// <typeparam name="T">The type of elements in the arrays being pooled. Must have a parameterless constructor.</typepar
 13public sealed class SwiftArrayPool<T> : IDisposable where T : new()
 14{
 15    #region Singleton Instance
 16
 17    /// <summary>
 18    /// A lazily initialized singleton instance of the array pool.
 19    /// </summary>
 120    private static readonly SwiftLazyDisposable<SwiftArrayPool<T>> _instance =
 221        new SwiftLazyDisposable<SwiftArrayPool<T>>(() => new SwiftArrayPool<T>(), LazyThreadSafetyMode.ExecutionAndPubli
 22
 23    /// <summary>
 24    /// Gets the shared instance of the pool.
 25    /// </summary>
 226    public static SwiftArrayPool<T> Shared => _instance.Value;
 27
 28    #endregion
 29
 30    #region Fields
 31
 32    /// <summary>
 33    /// A collection of object pools, keyed by the size of the arrays they manage.
 34    /// </summary>
 35    private readonly ConcurrentDictionary<int, SwiftObjectPool<T[]>> _sizePools;
 36
 37    /// <summary>
 38    /// Tracks whether the pool has been disposed.
 39    /// </summary>
 40    private volatile bool _disposed;
 41
 42    #endregion
 43
 44    #region Constructor
 45
 46    /// <summary>
 47    /// Initializes a new instance of the <see cref="SwiftArrayPool{T}"/> class with customizable behavior.
 48    /// </summary>
 49    /// <param name="createFunc">A function used to create new arrays (default: creates arrays of the specified size).</
 50    /// <param name="actionOnRelease">An action performed when an array is released back to the pool (default: clears th
 51    /// <param name="actionOnDestroy">An action performed when an array is removed from the pool (default: no action).</
 52    /// <param name="poolMaxCapacity">The maximum number of arrays each pool can hold for a specific size (default: 100)
 1353    public SwiftArrayPool(
 1354        Func<int, T[]> createFunc = null,
 1355        Action<T[]> actionOnRelease = null,
 1356        Action<T[]> actionOnDestroy = null,
 1357        int poolMaxCapacity = 100)
 1358    {
 1359        SwiftThrowHelper.ThrowIfNegativeOrZero(poolMaxCapacity, nameof(poolMaxCapacity));
 60
 1361        _sizePools = new ConcurrentDictionary<int, SwiftObjectPool<T[]>>();
 1362        PoolMaxCapacity = poolMaxCapacity;
 63
 2464        CreateFunc = createFunc ?? (size => new T[size]);
 1365        ActionOnRelease = actionOnRelease ?? (array =>
 1966            Array.Clear(array, 0, array.Length));
 1367        ActionOnDestroy = actionOnDestroy;
 1368    }
 69
 70    #endregion
 71
 72    #region Properties
 73
 74    /// <summary>
 75    /// Gets the function used to create new arrays.
 76    /// </summary>
 1277    public Func<int, T[]> CreateFunc { get; }
 78
 79    /// <summary>
 80    /// Gets the action performed when an array is released back to the pool.
 81    /// </summary>
 1282    public Action<T[]> ActionOnRelease { get; }
 83
 84    /// <summary>
 85    /// Gets the action performed when an array is removed from the pool.
 86    /// </summary>
 1287    public Action<T[]> ActionOnDestroy { get; }
 88
 89    /// <summary>
 90    /// Gets the maximum number of arrays each pool can hold for a specific size.
 91    /// </summary>
 1292    public int PoolMaxCapacity { get; }
 93
 94    #endregion
 95
 96    #region Collection Manipulation
 97
 98    /// <summary>
 99    /// Rents an array of the specified size from the pool. If no pool exists for the size, a new one is created.
 100    /// </summary>
 101    /// <param name="size">The desired size of the array.</param>
 102    /// <returns>An array of the specified size, either newly created or retrieved from the pool.</returns>
 103    /// <exception cref="ArgumentException">Thrown if the specified size is less than or equal to 0.</exception>
 104    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 105    public T[] Rent(int size)
 18106    {
 18107        SwiftThrowHelper.ThrowIfDisposed(_disposed, nameof(SwiftArrayPool<T>));
 16108        SwiftThrowHelper.ThrowIfNegativeOrZero(size, nameof(size));
 109
 26110        return _sizePools.GetOrAdd(size, key => CreatePoolForSize(key)).Rent();
 14111    }
 112
 113    /// <summary>
 114    /// Releases an array back to the pool for reuse. If no pool exists for the array's size, it is cleared and discarde
 115    /// </summary>
 116    /// <param name="array">The array to release back to the pool.</param>
 117    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 118    public void Release(T[] array)
 12119    {
 12120        SwiftThrowHelper.ThrowIfDisposed(_disposed, nameof(SwiftArrayPool<T>));
 121
 12122        if (array == null || array.Length == 0) return;
 123
 8124        if (_sizePools.TryGetValue(array.Length, out var pool))
 7125            pool.Release(array);
 126        else
 1127            Array.Clear(array, 0, array.Length);  // Handle large or unusual sizes by discarding
 10128    }
 129
 130    /// <summary>
 131    /// Clears all object pools, releasing any pooled arrays and resetting the state.
 132    /// </summary>
 133    public void Clear()
 2134    {
 2135        if (_disposed) return;
 136
 12137        foreach (SwiftObjectPool<T[]> pool in _sizePools.Values)
 3138            pool.Clear();
 139
 2140        _sizePools.Clear();
 2141    }
 142
 143    /// <summary>
 144    /// Creates a new object pool for managing arrays of the specified size.
 145    /// </summary>
 146    /// <param name="size">The size of arrays to be managed by the pool.</param>
 147    /// <returns>A new instance of <see cref="SwiftObjectPool{T}"/> for managing arrays of the specified size.</returns>
 148    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 149    private SwiftObjectPool<T[]> CreatePoolForSize(int size)
 12150    {
 12151        return new SwiftObjectPool<T[]>(
 12152            createFunc: () => CreateFunc(size),
 12153            actionOnRelease: ActionOnRelease,
 12154            actionOnDestroy: ActionOnDestroy,
 12155            maxSize: PoolMaxCapacity
 12156        );
 12157    }
 158
 159    #endregion
 160
 161    #region IDisposable Implementation
 162
 163    /// <summary>
 164    /// Releases all resources used by the SwiftArrayPool.
 165    /// It is important to call Dispose() to release pooled arrays, preventing potential memory leaks.
 166    /// </summary>
 167    public void Dispose()
 12168    {
 12169        if (_disposed) return;
 170
 12171        _disposed = true;
 54172        foreach (SwiftObjectPool<T[]> pool in _sizePools.Values)
 9173            pool.Dispose();
 12174        _sizePools.Clear();
 175
 176        // Suppress finalization to prevent unnecessary GC overhead
 12177        GC.SuppressFinalize(this);
 12178    }
 179
 10180    ~SwiftArrayPool() => Dispose();
 181
 182    #endregion
 183}