using System; using System.Runtime.CompilerServices; /*https://github.com/sidristij/memory-pools*/ namespace MemoryPools.Memory.Pooling { /// <summary> /// This pool returns NEW instance if pool is empty and old if non-empty. /// When got, user can return instance back to pool. If not returned, GC will collect it /// This means, that if you want to detect 'leaks', you should: /// 1) add [CallerFilePath], [CallerLineNumber] to your Init() method parameters /// 2) make finalizer in your type and log saved fileName and lineNumber from (1). /// </summary> /// <code> /// MyType Init(int arg0, string arg1 /// #if DEBUG /// , [CallerFilePath] string fileName = default, [CallerLineNumber] int lineNumber = default /// #endif /// ) /// { /// #if DEBUG /// _fileName = fileName; /// _lineNumber = lineNumber; /// #endif /// } /// #if DEBUG /// ~MyType() /// { /// Console.WriteLine($" - {_fileName}:{_lineNumber}"); /// } /// #endif /// </code> public sealed class BucketsBasedCrossThreadsMemoryPool<T> { private BucketsBasedCrossThreadsArrayPool<T> _pool; [ThreadStatic] private static BucketsBasedCrossThreadsMemoryPool<T> _mempool; internal BucketsBasedCrossThreadsArrayPool<T> _arraysPool => _pool ??= new BucketsBasedCrossThreadsArrayPool<T>(); public static BucketsBasedCrossThreadsMemoryPool<T> Shared => _mempool ??= new BucketsBasedCrossThreadsMemoryPool<T>(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public CountdownMemoryOwner<T> Rent(int minBufferSize = -1) { return Pool<CountdownMemoryOwner<T>>.Get().Init(_arraysPool.Rent(minBufferSize), minBufferSize); } } }