Files
even-perfect-numbers-scanner/PerfectNumbers.Core/PartialFactorResult.cs
T

123 lines
3.4 KiB
C#

namespace PerfectNumbers.Core
{
public sealed class PartialFactorResult
{
[ThreadStatic]
private static PartialFactorResult? s_poolHead;
public ulong[]? Factors;
public int[]? Exponents;
private PartialFactorResult? _next;
public ulong Cofactor;
public bool FullyFactored;
public int Count;
public bool CofactorIsPrime;
private PartialFactorResult()
{
}
public static PartialFactorResult Rent(in ulong[]? factors, in int[]? exponents, ulong cofactor, bool fullyFactored, int count, bool cofactorIsPrime)
{
PartialFactorResult? instance = s_poolHead;
if (instance is null)
{
instance = new PartialFactorResult();
}
else
{
s_poolHead = instance._next;
}
instance._next = null;
instance.Factors = factors;
instance.Exponents = exponents;
instance.Cofactor = cofactor;
instance.FullyFactored = fullyFactored;
instance.Count = count;
instance.CofactorIsPrime = cofactorIsPrime;
return instance;
}
public static PartialFactorResult Rent(ulong cofactor, bool fullyFactored, int count, bool cofactorIsPrime)
{
PartialFactorResult? instance = s_poolHead;
if (instance is null)
{
instance = new PartialFactorResult();
}
else
{
s_poolHead = instance._next;
}
instance._next = null;
instance.Factors = null;
instance.Exponents = null;
instance.Cofactor = cofactor;
instance.FullyFactored = fullyFactored;
instance.Count = count;
instance.CofactorIsPrime = cofactorIsPrime;
return instance;
}
public static readonly PartialFactorResult Empty = new()
{
Cofactor = 1UL,
FullyFactored = true
};
public PartialFactorResult WithAdditionalPrime(ulong prime)
{
ulong[]? source = Factors;
int sourceCount = Count;
int[] exponents;
if (source is null || sourceCount == 0)
{
source = ThreadStaticPools.UlongPool.Rent(1);
exponents = ThreadStaticPools.IntPool.Rent(1);
// source = new ulong[1];
// exponents = new int[1];
source[0] = prime;
exponents[0] = 1;
return Rent(source, exponents, 1UL, true, 1, false);
}
ulong[] extended = ThreadStaticPools.UlongPool.Rent(sourceCount + 1);
Array.Copy(source, 0, extended, 0, sourceCount);
extended[sourceCount] = prime;
exponents = ThreadStaticPools.IntPool.Rent(sourceCount + 1);
Array.Copy(Exponents!, 0, exponents, 0, sourceCount);
exponents[sourceCount] = 1;
Array.Sort(extended, exponents, 0, sourceCount + 1);
return Rent(extended, exponents, 1UL, true, sourceCount + 1, false);
}
public void Dispose()
{
if (this != Empty)
{
ulong[]? factors = Factors;
if (factors is not null)
{
int[] exponents = Exponents!;
Factors = null;
Exponents = null;
// if (factors.Length > 1)
// {
ThreadStaticPools.UlongPool.Return(factors, clearArray: false);
ThreadStaticPools.IntPool.Return(exponents, clearArray: false);
// }
}
_next = s_poolHead;
s_poolHead = this;
}
}
}
}