using PerfectNumbers.Core.Gpu; namespace PerfectNumbers.Core { public sealed class PartialFactorResult(in MontgomeryDivisorData divisorData) { [ThreadStatic] private static PartialFactorResult? s_poolHead; public readonly ulong[] Factors = new ulong[PrimeOrderConstants.GpuSmallPrimeFactorSlots]; public readonly int[] Exponents = new int[PrimeOrderConstants.GpuSmallPrimeFactorSlots]; public readonly FixedCapacityStack CompositeStack = new (PrimeOrderConstants.GpuSmallPrimeFactorSlots); public readonly List PendingFactors = new (PrimeOrderConstants.GpuSmallPrimeFactorSlots); public readonly ulong[] StackCandidates = new ulong[PrimeOrderConstants.GpuSmallPrimeFactorSlots << 3]; public readonly bool[] StackEvaluations = new bool[PrimeOrderConstants.GpuSmallPrimeFactorSlots << 3]; public ExponentRemainderStepperCpu ExponentRemainderStepper = new(divisorData); private PartialFactorResult? _next; public ulong Cofactor; public bool FullyFactored; public int Count; public bool CofactorIsPrime; public static PartialFactorResult Rent(in MontgomeryDivisorData divisorData) { PartialFactorResult? instance = s_poolHead; if (instance is null) { instance = new PartialFactorResult(divisorData); } else { s_poolHead = instance._next; if (!instance.ExponentRemainderStepper.MatchesDivisor(divisorData, 0UL)) { instance.ExponentRemainderStepper = new(divisorData, 0UL); } } instance._next = null; instance.Cofactor = 0UL; instance.FullyFactored = false; instance.Count = 0; instance.CofactorIsPrime = false; return instance; } public static readonly PartialFactorResult Empty = new(MontgomeryDivisorData.Empty) { Cofactor = 1UL, FullyFactored = true }; public void WithAdditionalPrime(ulong prime) { ulong[]? sourceFactors = Factors; int sourceCount = Count; if (sourceCount == 0) { InitializeWithPrime(prime); return; } int[] sourceExponents = Exponents!; int newSize = sourceCount + 1; sourceFactors[sourceCount] = prime; sourceExponents[sourceCount] = 1; Array.Sort(sourceFactors, sourceExponents, 0, newSize); Cofactor = 1UL; FullyFactored = true; Count = newSize; CofactorIsPrime = false; } private void InitializeWithPrime(ulong prime) { Factors[0] = prime; Exponents[0] = 1; Cofactor = 1UL; FullyFactored = true; Count = 1; CofactorIsPrime = false; } public void Dispose() { if (this != Empty) { _next = s_poolHead; s_poolHead = this; } } } }