From 5f3313a3bf927829df8cdebc9b434d2c4510135c Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Thu, 18 Jan 2024 16:57:23 -0800 Subject: [PATCH] Use runInterleaved in lastLeqMulti --- ConflictSet.cpp | 110 ++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 60 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index ae44e47..4049c1b 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -106,6 +106,43 @@ struct Iterator { int cmp; }; +// Call Stepwise::step for each element of remaining until it returns true. +// Applies a permutation to remaining as a side effect. +template +void runInterleaved(std::span remaining, int stepLimit = -1) { + while (remaining.size() > 0) { + for (int i = 0; i < int(remaining.size());) { + if (stepLimit-- == 0) { + return; + } + bool done = remaining[i].step(); + if (done) { + if (i != int(remaining.size()) - 1) { + using std::swap; + swap(remaining[i], remaining.back()); + } + remaining = remaining.subspan(0, remaining.size() - 1); + } else { + ++i; + } + } + } +}; + +template +void runSequential(std::span remaining, int stepLimit = -1) { + for (auto &r : remaining) { + if (stepLimit-- == 0) { + return; + } + while (!r.step()) { + if (stepLimit-- == 0) { + return; + } + } + } +} + struct StepwiseLastLeq { Node *current; Node *result; @@ -147,17 +184,16 @@ void lastLeqMulti(Node *root, std::span keys, Iterator *results) { // Descend until queries for front and back diverge Node *current = root; Node *resultP = nullptr; - auto stepwiseLastLeqBegin = - StepwiseLastLeq(current, resultP, keys.front(), -1); - auto stepwiseLastLeqEnd = StepwiseLastLeq(current, resultP, keys.back(), -1); + auto stepwiseFront = StepwiseLastLeq(current, resultP, keys.front(), -1); + auto stepwiseBack = StepwiseLastLeq(current, resultP, keys.back(), -1); for (;;) { - bool done1 = stepwiseLastLeqBegin.step(); - bool done2 = stepwiseLastLeqEnd.step(); - if (!done1 && !done2 && stepwiseLastLeqBegin.c == stepwiseLastLeqEnd.c) { - assert(stepwiseLastLeqBegin.current == stepwiseLastLeqEnd.current); - assert(stepwiseLastLeqBegin.result == stepwiseLastLeqEnd.result); - current = stepwiseLastLeqBegin.current; - resultP = stepwiseLastLeqBegin.result; + bool done1 = stepwiseFront.step(); + bool done2 = stepwiseBack.step(); + if (!done1 && !done2 && stepwiseFront.c == stepwiseBack.c) { + assert(stepwiseFront.current == stepwiseBack.current); + assert(stepwiseFront.result == stepwiseBack.result); + current = stepwiseFront.current; + resultP = stepwiseFront.result; } else { break; } @@ -170,22 +206,11 @@ void lastLeqMulti(Node *root, std::span keys, Iterator *results) { *iter++ = StepwiseLastLeq(current, resultP, k, index++); } } - auto remaining = + auto stepwiseSpan = std::span(stepwiseLastLeqs.get(), keys.size()); - while (remaining.size() > 0) { - for (int i = 0; i < int(remaining.size());) { - bool done = remaining[i].step(); - if (done) { - const auto &c = remaining[i]; - results[c.index] = Iterator{c.result, c.resultC}; - if (i != int(remaining.size()) - 1) { - remaining[i] = remaining.back(); - } - remaining = remaining.subspan(0, remaining.size() - 1); - } else { - ++i; - } - } + runInterleaved(stepwiseSpan); + for (const auto &stepwise : stepwiseSpan) { + results[stepwise.index] = Iterator{stepwise.result, stepwise.resultC}; } } @@ -401,41 +426,6 @@ bool checkInvariants(Node *node) { return success; } -template -void runInterleaved(std::span remaining, int stepLimit = -1) { - while (remaining.size() > 0) { - for (int i = 0; i < int(remaining.size());) { - if (stepLimit-- == 0) { - return; - } - bool done = remaining[i].step(); - if (done) { - if (i != int(remaining.size()) - 1) { - using std::swap; - swap(remaining[i], remaining.back()); - } - remaining = remaining.subspan(0, remaining.size() - 1); - } else { - ++i; - } - } - } -}; - -template -void runSequential(std::span remaining, int stepLimit = -1) { - for (auto &r : remaining) { - if (stepLimit-- == 0) { - return; - } - while (!r.step()) { - if (stepLimit-- == 0) { - return; - } - } - } -} - } // namespace struct ConflictSet::Impl {