From c8d6143ab767d1a120745963845aaad1293827bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Lema=C5=84czyk?= Date: Mon, 13 Oct 2025 18:12:06 +0200 Subject: [PATCH] Simplify by-divisor buffer guards and document prime ordering --- EvenPerfectBitScanner/Program.cs | 2 +- ...MersenneNumberDivisorByDivisorCpuTester.cs | 36 +++++++------------ 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/EvenPerfectBitScanner/Program.cs b/EvenPerfectBitScanner/Program.cs index 06a1bf1..b08f418 100644 --- a/EvenPerfectBitScanner/Program.cs +++ b/EvenPerfectBitScanner/Program.cs @@ -1030,7 +1030,7 @@ internal static class Program Console.WriteLine(" --use-order test primality via q order"); Console.WriteLine(" --workaround-mod avoid '%' operator on the GPU"); // mod-automaton removed - Console.WriteLine(" --filter-p= process only p from previous run results (required for --mersenne=bydivisor)"); + Console.WriteLine(" --filter-p= process only p from previous run results (required for --mersenne=bydivisor; primes must be strictly increasing)"); Console.WriteLine(" --write-batch-size= overwrite frequency of disk writes (default 100 lines)"); Console.WriteLine(" --gcd-filter enable early sieve based on GCD"); Console.WriteLine(" --help, -help, --?, -?, /? show this help message"); diff --git a/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs b/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs index f3d3382..fed7e76 100644 --- a/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs +++ b/PerfectNumbers.Core/Cpu/MersenneNumberDivisorByDivisorCpuTester.cs @@ -808,9 +808,8 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv return; } - // Sessions release pooled buffers between scans, so the null checks stay in place to avoid using returned arrays - // when a session is reset for a subsequent divisor. - if (requiredLength <= _bufferCapacity && _primeDeltas is not null && _cycleRemainders is not null && _residues is not null) + // Sessions release pooled buffers between scans; a single null check covers every array because buffers are rented and returned together. + if (requiredLength <= _bufferCapacity && _primeDeltas is not null) { return; } @@ -837,25 +836,18 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv private void ReturnBuffers() { - // Buffers are lazily allocated per session; return whichever arrays were rented before the next batch. - if (_primeDeltas is not null) + // Buffers are lazily allocated per session; the _primeDeltas guard applies to every pooled array because sessions rent and release them together. + if (_primeDeltas is null) { - ArrayPool.Shared.Return(_primeDeltas, clearArray: false); - _primeDeltas = null; - } - - if (_cycleRemainders is not null) - { - ArrayPool.Shared.Return(_cycleRemainders, clearArray: false); - _cycleRemainders = null; - } - - if (_residues is not null) - { - ArrayPool.Shared.Return(_residues, clearArray: false); - _residues = null; + return; } + ArrayPool.Shared.Return(_primeDeltas, clearArray: false); + ArrayPool.Shared.Return(_cycleRemainders!, clearArray: false); + ArrayPool.Shared.Return(_residues!, clearArray: false); + _primeDeltas = null; + _cycleRemainders = null; + _residues = null; _bufferCapacity = 0; } @@ -870,14 +862,10 @@ public sealed class MersenneNumberDivisorByDivisorCpuTester : IMersenneNumberDiv ulong previous = primes[0]; deltas[0] = previous; + // Production batches feed strictly increasing primes; callers outside the scanning path must uphold the contract. for (int i = 1; i < primes.Length; i++) { ulong current = primes[i]; - if (current <= previous) - { - throw new ArgumentOutOfRangeException(nameof(primes), "Primes must be strictly increasing."); - } - deltas[i] = current - previous; previous = current; }