Use runInterleaved in lastLeqMulti
This commit is contained in:
110
ConflictSet.cpp
110
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 <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 {
|
||||
|
Reference in New Issue
Block a user