Merge pull request #25 from mlemanczyk/codex/optimize-resultsparser-to-use-sorted-pendingresults
Optimize pending result handling in results parser
This commit is contained in:
1 file changed
+73
-22
@@ -122,7 +122,7 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
CandidateResult result = ParseLine(currentLine);
|
CandidateResult result = ParseLine(currentLine);
|
||||||
pendingResults.Add(result);
|
InsertPendingResult(pendingResults, result);
|
||||||
DrainPrimeMatches(pendingResults, primeResults, ref currentPrime, primeEnumerator, false);
|
DrainPrimeMatches(pendingResults, primeResults, ref currentPrime, primeEnumerator, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@ internal static class Program
|
|||||||
bool extractedPrime = ExtractPrimeEntries(pendingResults, primeResults, currentPrime);
|
bool extractedPrime = ExtractPrimeEntries(pendingResults, primeResults, currentPrime);
|
||||||
if (extractedPrime)
|
if (extractedPrime)
|
||||||
{
|
{
|
||||||
if (!TryAdvancePrime(primeEnumerator, ref currentPrime))
|
if (!TryAdvancePrime(primeEnumerator, ref currentPrime, pendingResults))
|
||||||
{
|
{
|
||||||
pendingResults.Clear();
|
pendingResults.Clear();
|
||||||
return;
|
return;
|
||||||
@@ -288,7 +288,7 @@ internal static class Program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryAdvancePrime(primeEnumerator, ref currentPrime))
|
if (!TryAdvancePrime(primeEnumerator, ref currentPrime, pendingResults))
|
||||||
{
|
{
|
||||||
pendingResults.Clear();
|
pendingResults.Clear();
|
||||||
return;
|
return;
|
||||||
@@ -303,39 +303,61 @@ internal static class Program
|
|||||||
List<CandidateResult> primeResults,
|
List<CandidateResult> primeResults,
|
||||||
ulong prime)
|
ulong prime)
|
||||||
{
|
{
|
||||||
bool found = false;
|
if (pendingResults.Count == 0)
|
||||||
for (int i = 0; i < pendingResults.Count; i++)
|
|
||||||
{
|
{
|
||||||
CandidateResult candidate = pendingResults[i];
|
return false;
|
||||||
if (candidate.P != prime)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
primeResults.Add(candidate);
|
int startIndex = FindFirstIndexAtLeast(pendingResults, prime);
|
||||||
pendingResults.RemoveAt(i);
|
if (startIndex >= pendingResults.Count)
|
||||||
i--;
|
{
|
||||||
found = true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
CandidateResult firstCandidate = pendingResults[startIndex];
|
||||||
|
if (firstCandidate.P != prime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int endIndex = startIndex + 1;
|
||||||
|
while (endIndex < pendingResults.Count && pendingResults[endIndex].P == prime)
|
||||||
|
{
|
||||||
|
endIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = startIndex; i < endIndex; i++)
|
||||||
|
{
|
||||||
|
primeResults.Add(pendingResults[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingResults.RemoveRange(startIndex, endIndex - startIndex);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RemoveEntriesBelowPrime(List<CandidateResult> pendingResults, ulong currentPrime)
|
private static void RemoveEntriesBelowPrime(List<CandidateResult> pendingResults, ulong currentPrime)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < pendingResults.Count; i++)
|
if (pendingResults.Count == 0)
|
||||||
{
|
{
|
||||||
if (pendingResults[i].P >= currentPrime)
|
return;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingResults.RemoveAt(i);
|
int removeCount = FindFirstIndexAtLeast(pendingResults, currentPrime);
|
||||||
i--;
|
if (removeCount == 0)
|
||||||
}
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool TryAdvancePrime(IEnumerator<ulong> primeEnumerator, ref ulong currentPrime)
|
pendingResults.RemoveRange(0, removeCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryAdvancePrime(
|
||||||
|
IEnumerator<ulong> primeEnumerator,
|
||||||
|
ref ulong currentPrime,
|
||||||
|
List<CandidateResult> pendingResults)
|
||||||
|
{
|
||||||
|
ulong minimumPending = pendingResults.Count > 0 ? pendingResults[0].P : 0UL;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
if (!primeEnumerator.MoveNext())
|
if (!primeEnumerator.MoveNext())
|
||||||
{
|
{
|
||||||
@@ -344,9 +366,38 @@ internal static class Program
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentPrime = primeEnumerator.Current;
|
currentPrime = primeEnumerator.Current;
|
||||||
|
}
|
||||||
|
while (pendingResults.Count > 0 && currentPrime < minimumPending);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void InsertPendingResult(List<CandidateResult> pendingResults, CandidateResult result)
|
||||||
|
{
|
||||||
|
int insertIndex = FindFirstIndexAtLeast(pendingResults, result.P);
|
||||||
|
pendingResults.Insert(insertIndex, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int FindFirstIndexAtLeast(List<CandidateResult> pendingResults, ulong value)
|
||||||
|
{
|
||||||
|
int low = 0;
|
||||||
|
int high = pendingResults.Count - 1;
|
||||||
|
while (low <= high)
|
||||||
|
{
|
||||||
|
int mid = low + ((high - low) >> 1);
|
||||||
|
ulong midValue = pendingResults[mid].P;
|
||||||
|
if (midValue < value)
|
||||||
|
{
|
||||||
|
low = mid + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
high = mid - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return low;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly record struct CandidateResult(ulong P, bool IsPerfect, string Csv)
|
private readonly record struct CandidateResult(ulong P, bool IsPerfect, string Csv)
|
||||||
{
|
{
|
||||||
public string ToCsv()
|
public string ToCsv()
|
||||||
|
|||||||
Reference in new issue
Block a user