Use runInterleaved in lastLeqMulti
This commit is contained in:
110
ConflictSet.cpp
110
ConflictSet.cpp
@@ -106,6 +106,43 @@ struct Iterator {
|
|||||||
int cmp;
|
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 {
|
struct StepwiseLastLeq {
|
||||||
Node *current;
|
Node *current;
|
||||||
Node *result;
|
Node *result;
|
||||||
@@ -147,17 +184,16 @@ void lastLeqMulti(Node *root, std::span<Key> keys, Iterator *results) {
|
|||||||
// Descend until queries for front and back diverge
|
// Descend until queries for front and back diverge
|
||||||
Node *current = root;
|
Node *current = root;
|
||||||
Node *resultP = nullptr;
|
Node *resultP = nullptr;
|
||||||
auto stepwiseLastLeqBegin =
|
auto stepwiseFront = StepwiseLastLeq(current, resultP, keys.front(), -1);
|
||||||
StepwiseLastLeq(current, resultP, keys.front(), -1);
|
auto stepwiseBack = StepwiseLastLeq(current, resultP, keys.back(), -1);
|
||||||
auto stepwiseLastLeqEnd = StepwiseLastLeq(current, resultP, keys.back(), -1);
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bool done1 = stepwiseLastLeqBegin.step();
|
bool done1 = stepwiseFront.step();
|
||||||
bool done2 = stepwiseLastLeqEnd.step();
|
bool done2 = stepwiseBack.step();
|
||||||
if (!done1 && !done2 && stepwiseLastLeqBegin.c == stepwiseLastLeqEnd.c) {
|
if (!done1 && !done2 && stepwiseFront.c == stepwiseBack.c) {
|
||||||
assert(stepwiseLastLeqBegin.current == stepwiseLastLeqEnd.current);
|
assert(stepwiseFront.current == stepwiseBack.current);
|
||||||
assert(stepwiseLastLeqBegin.result == stepwiseLastLeqEnd.result);
|
assert(stepwiseFront.result == stepwiseBack.result);
|
||||||
current = stepwiseLastLeqBegin.current;
|
current = stepwiseFront.current;
|
||||||
resultP = stepwiseLastLeqBegin.result;
|
resultP = stepwiseFront.result;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -170,22 +206,11 @@ void lastLeqMulti(Node *root, std::span<Key> keys, Iterator *results) {
|
|||||||
*iter++ = StepwiseLastLeq(current, resultP, k, index++);
|
*iter++ = StepwiseLastLeq(current, resultP, k, index++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto remaining =
|
auto stepwiseSpan =
|
||||||
std::span<StepwiseLastLeq>(stepwiseLastLeqs.get(), keys.size());
|
std::span<StepwiseLastLeq>(stepwiseLastLeqs.get(), keys.size());
|
||||||
while (remaining.size() > 0) {
|
runInterleaved(stepwiseSpan);
|
||||||
for (int i = 0; i < int(remaining.size());) {
|
for (const auto &stepwise : stepwiseSpan) {
|
||||||
bool done = remaining[i].step();
|
results[stepwise.index] = Iterator{stepwise.result, stepwise.resultC};
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,41 +426,6 @@ bool checkInvariants(Node *node) {
|
|||||||
return success;
|
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
|
} // namespace
|
||||||
|
|
||||||
struct ConflictSet::Impl {
|
struct ConflictSet::Impl {
|
||||||
|
Reference in New Issue
Block a user