Use runInterleaved in lastLeqMulti

This commit is contained in:
2024-01-18 16:57:23 -08:00
parent 1bab3b7555
commit 5f3313a3bf

View File

@@ -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 <class Stepwise>
void runInterleaved(std::span<Stepwise> 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 <class Stepwise>
void runSequential(std::span<Stepwise> 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<Key> 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<Key> keys, Iterator *results) {
*iter++ = StepwiseLastLeq(current, resultP, k, index++);
}
}
auto remaining =
auto stepwiseSpan =
std::span<StepwiseLastLeq>(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 <class Stepwise>
void runInterleaved(std::span<Stepwise> 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 <class Stepwise>
void runSequential(std::span<Stepwise> remaining, int stepLimit = -1) {
for (auto &r : remaining) {
if (stepLimit-- == 0) {
return;
}
while (!r.step()) {
if (stepLimit-- == 0) {
return;
}
}
}
}
} // namespace
struct ConflictSet::Impl {