PrimeOrderCalculator.PartialFactorCpu simplified to work only with spans and throw exception if the number of factors is exceeded. PrimeOrderMode removed in favor of bool flag.

This commit is contained in:
mlemanczyk committed 2025-12-10 12:47:25 +01:00
1 parent 72890bf343
commit 7a242b3bfa
15 files changed
+337 -302

No files matched your search

+72 -77
View File
@@ -1,75 +1,75 @@
namespace PerfectNumbers.Core
{
public sealed class PartialFactorResult
{
[ThreadStatic]
private static PartialFactorResult? s_poolHead;
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;
private PartialFactorResult? _next;
public ulong Cofactor;
public bool FullyFactored;
public int Count;
public bool CofactorIsPrime;
private PartialFactorResult()
{
}
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;
}
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._next = null;
instance.Factors = factors;
instance.Exponents = exponents;
instance.Cofactor = cofactor;
instance.FullyFactored = fullyFactored;
instance.FullyFactored = fullyFactored;
instance.Count = count;
instance.CofactorIsPrime = cofactorIsPrime;
return instance;
}
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;
}
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._next = null;
instance.Factors = null;
instance.Exponents = null;
instance.Cofactor = cofactor;
instance.FullyFactored = fullyFactored;
instance.FullyFactored = fullyFactored;
instance.Count = count;
instance.CofactorIsPrime = cofactorIsPrime;
return instance;
}
return instance;
}
public static readonly PartialFactorResult Empty = new()
public static readonly PartialFactorResult Empty = new()
{
Cofactor = 1UL,
FullyFactored = true
};
public void WithAdditionalPrime(ulong prime)
{
ulong[]? sourceFactors = Factors;
public void WithAdditionalPrime(ulong prime)
{
ulong[]? sourceFactors = Factors;
int sourceCount = Count;
if (sourceFactors is null || sourceCount == 0)
{
@@ -78,14 +78,12 @@ namespace PerfectNumbers.Core
}
int newSize = sourceCount + 1;
int[] extendedExponents;
ulong[] extendedFactors = sourceFactors.Length >= newSize
? sourceFactors
: ResizeFactors(sourceFactors, sourceCount, newSize);
int[] sourceExponents = Exponents!;
extendedExponents = sourceExponents.Length >= newSize
int[] extendedExponents = sourceExponents.Length >= newSize
? sourceExponents
: ResizeExponents(sourceCount, newSize, sourceExponents);
@@ -99,33 +97,31 @@ namespace PerfectNumbers.Core
FullyFactored = true;
Count = newSize;
CofactorIsPrime = false;
}
}
private static int[] ResizeExponents(int sourceCount, int newSize, int[] sourceExponents)
private static int[] ResizeExponents(int sourceCount, int newSize, in int[] sourceExponents)
{
int[] extendedExponents = ThreadStaticPools.IntPool.Rent(newSize);
int[] extendedExponents = Pools.ExclusiveIntArray.Rent(newSize);
Array.Copy(sourceExponents, 0, extendedExponents, 0, sourceCount);
ThreadStaticPools.IntPool.Return(sourceExponents, clearArray: false);
Pools.ExclusiveIntArray.Return(sourceExponents);
return extendedExponents;
}
private static ulong[] ResizeFactors(ulong[] sourceFactors, int sourceCount, int newSize)
private static ulong[] ResizeFactors(in ulong[] sourceFactors, int sourceCount, int newSize)
{
ulong[] extendedFactors = ThreadStaticPools.UlongPool.Rent(newSize);
ulong[] extendedFactors = Pools.ExclusiveUlongArray.Rent(newSize);
Array.Copy(sourceFactors, 0, extendedFactors, 0, sourceCount);
ThreadStaticPools.UlongPool.Return(sourceFactors, clearArray: false);
Pools.ExclusiveUlongArray.Return(sourceFactors);
return extendedFactors;
}
private void InitializeWithPrime(ulong prime)
{
ulong[] source = ThreadStaticPools.UlongPool.Rent(1);
int[] exponents = ThreadStaticPools.IntPool.Rent(1);
// source = new ulong[1];
// exponents = new int[1];
source[0] = prime;
ulong[] factors = Pools.ExclusiveUlongArray.Rent(1);
int[] exponents = Pools.ExclusiveIntArray.Rent(1);
factors[0] = prime;
exponents[0] = 1;
Factors = source;
Factors = factors;
Exponents = exponents;
Cofactor = 1UL;
FullyFactored = true;
@@ -134,26 +130,25 @@ namespace PerfectNumbers.Core
}
public void Dispose()
{
if (this != Empty)
{
ulong[]? factors = Factors;
if (factors is not null)
{
{
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);
// }
}
Pools.ExclusiveUlongArray.Return(factors);
Pools.ExclusiveIntArray.Return(exponents);
}
_next = s_poolHead;
s_poolHead = this;
}
}
}
_next = s_poolHead;
s_poolHead = this;
}
}
}
}