using System; using System.Buffers; using System.Collections.Generic; using System.Runtime.CompilerServices; using PerfectNumbers.Core.Cpu; namespace PerfectNumbers.Core { public readonly struct ThreadStaticPools { [ThreadStatic] private static ArrayPool? _factorEntryPool; public static ArrayPool FactorEntryPool { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _factorEntryPool ??= ArrayPool.Create(); } } [ThreadStatic] private static ArrayPool? _factorEntry128Pool; public static ArrayPool FactorEntry128Pool { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _factorEntry128Pool ??= ArrayPool.Create(); } } [ThreadStatic] private static ArrayPool>? _factorKeyValuePairPool; public static ArrayPool> FactorKeyValuePairPool { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _factorKeyValuePairPool ??= ArrayPool>.Create(); } } [ThreadStatic] private static MersenneCpuDivisorScanSession? _mersenneCpuDivisorSession; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static MersenneCpuDivisorScanSession? RentMersenneCpuDivisorSession() { MersenneCpuDivisorScanSession? session = _mersenneCpuDivisorSession; if (session is null) { return null; } _mersenneCpuDivisorSession = null; session.Reset(); return session; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ReturnMersenneCpuDivisorSession(MersenneCpuDivisorScanSession session) { _mersenneCpuDivisorSession = session; } [ThreadStatic] private static ArrayPool? _ulongPool; public static ArrayPool UlongPool { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _ulongPool ??= ArrayPool.Create(); } } [ThreadStatic] private static ArrayPool? _intPool; public static ArrayPool IntPool { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _intPool ??= ArrayPool.Create(); } } [ThreadStatic] private static List>? _ulongListPool; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List RentUlongList(int capacityHint) { List>? pool = _ulongListPool; if (pool is not null && pool.Count > 0) { int lastIndex = pool.Count - 1; List list = pool[lastIndex]; pool.RemoveAt(lastIndex); if (list.Count > 0) { list.Clear(); } if (list.Capacity < capacityHint) { list.Capacity = capacityHint; } return list; } return new List(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnUlongList(List list) { List>? pool = _ulongListPool; if (pool is null) { pool = new List>(4); _ulongListPool = pool; } pool.Add(list); } [ThreadStatic] private static List>? _ulongStackPool; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Stack RentUlongStack(int capacityHint) { List>? pool = _ulongStackPool; if (pool is not null && pool.Count > 0) { int lastIndex = pool.Count - 1; Stack stack = pool[lastIndex]; pool.RemoveAt(lastIndex); if (stack.Count > 0) { stack.Clear(); } if (stack.Count < capacityHint) { stack.EnsureCapacity(capacityHint); } return stack; } return new Stack(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnUlongStack(Stack stack) { List>? pool = _ulongStackPool; if (pool is null) { pool = new List>(4); _ulongStackPool = pool; } pool.Add(stack); } [ThreadStatic] private static List>? _ulongIntDictionaryPool; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Dictionary RentUlongIntDictionary(int capacityHint) { List>? pool = _ulongIntDictionaryPool; if (pool is not null && pool.Count > 0) { int lastIndex = pool.Count - 1; Dictionary dictionary = pool[lastIndex]; pool.RemoveAt(lastIndex); if (dictionary.Count > 0) { dictionary.Clear(); } if (dictionary.Count < capacityHint) { dictionary.EnsureCapacity(capacityHint); } return dictionary; } return new Dictionary(capacityHint); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnUlongIntDictionary(Dictionary dictionary) { List>? pool = _ulongIntDictionaryPool; if (pool is null) { pool = new List>(4); _ulongIntDictionaryPool = pool; } pool.Add(dictionary); } [ThreadStatic] private static Dictionary? _mersenneFactorCacheDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Dictionary RentMersenneFactorCacheDictionary() { Dictionary? cache = _mersenneFactorCacheDictionary; if (cache is null) { return new Dictionary(8); } _mersenneFactorCacheDictionary = null; cache.Clear(); return cache; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnMersenneFactorCacheDictionary(Dictionary cache) { for (Dictionary.Enumerator enumerator = cache.GetEnumerator(); enumerator.MoveNext();) { enumerator.Current.Value.ReturnToPool(); } cache.Clear(); _mersenneFactorCacheDictionary = cache; } [ThreadStatic] private static MersenneDivisorCycles.FactorCacheEntry? _factorCacheEntryPoolHead; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MersenneDivisorCycles.FactorCacheEntry RentFactorCacheEntry() { MersenneDivisorCycles.FactorCacheEntry? entry = _factorCacheEntryPoolHead; if (entry is null) { entry = new MersenneDivisorCycles.FactorCacheEntry(); } else { _factorCacheEntryPoolHead = entry.Next; } entry.Reset(); return entry; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnFactorCacheEntry(MersenneDivisorCycles.FactorCacheEntry entry) { entry.Next = _factorCacheEntryPoolHead; _factorCacheEntryPoolHead = entry; } [ThreadStatic] private static Dictionary? _factorCountDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Dictionary RentFactorCountDictionary() { Dictionary? dictionary = _factorCountDictionary; if (dictionary is null) { return new Dictionary(8); } _factorCountDictionary = null; dictionary.Clear(); return dictionary; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnFactorCountDictionary(Dictionary dictionary) { dictionary.Clear(); _factorCountDictionary = dictionary; } [ThreadStatic] private static Dictionary? _factorScratchDictionary; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Dictionary RentFactorScratchDictionary() { Dictionary? dictionary = _factorScratchDictionary; if (dictionary is null) { return new Dictionary(8); } _factorScratchDictionary = null; dictionary.Clear(); return dictionary; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ReturnFactorScratchDictionary(Dictionary dictionary) { dictionary.Clear(); _factorScratchDictionary = dictionary; } } }