Add "iter" state
This commit is contained in:
@@ -3040,6 +3040,7 @@ struct CheckJob {
|
|||||||
namespace check_point_read_state_machine {
|
namespace check_point_read_state_machine {
|
||||||
|
|
||||||
CheckJob::continuation down_left_spine(CheckJob *job);
|
CheckJob::continuation down_left_spine(CheckJob *job);
|
||||||
|
CheckJob::continuation iter(CheckJob *job);
|
||||||
|
|
||||||
// Logically this is the same as performing firstGeq and then checking against
|
// Logically this is the same as performing firstGeq and then checking against
|
||||||
// point or range version according to cmp, but this version short circuits as
|
// point or range version according to cmp, but this version short circuits as
|
||||||
@@ -3049,21 +3050,45 @@ CheckJob::continuation begin(CheckJob *job) {
|
|||||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||||
fprintf(stderr, "Check point read: %s\n", printable(key).c_str());
|
fprintf(stderr, "Check point read: %s\n", printable(key).c_str());
|
||||||
#endif
|
#endif
|
||||||
for (;; ++job->tls->point_read_iterations_accum) {
|
return iter(job);
|
||||||
if (job->begin.size() == 0) {
|
}
|
||||||
if (job->n->entryPresent) {
|
|
||||||
job->setResult(job->n->entry.pointVersion <= job->readVersion);
|
CheckJob::continuation iter(CheckJob *job) {
|
||||||
|
if (job->begin.size() == 0) {
|
||||||
|
if (job->n->entryPresent) {
|
||||||
|
job->setResult(job->n->entry.pointVersion <= job->readVersion);
|
||||||
|
return nullptr; // Done
|
||||||
|
}
|
||||||
|
job->n = getFirstChildExists(job->n);
|
||||||
|
return down_left_spine;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto [child, maxV] = getChildAndMaxVersion(job->n, job->begin[0]);
|
||||||
|
if (child == nullptr) {
|
||||||
|
auto c = getChildGeq(job->n, job->begin[0]);
|
||||||
|
if (c != nullptr) {
|
||||||
|
job->n = c;
|
||||||
|
return down_left_spine;
|
||||||
|
} else {
|
||||||
|
job->n = nextSibling(job->n);
|
||||||
|
if (job->n == nullptr) {
|
||||||
|
job->setResult(true);
|
||||||
return nullptr; // Done
|
return nullptr; // Done
|
||||||
}
|
}
|
||||||
job->n = getFirstChildExists(job->n);
|
|
||||||
return down_left_spine;
|
return down_left_spine;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto [child, maxV] = getChildAndMaxVersion(job->n, job->begin[0]);
|
job->n = child;
|
||||||
if (child == nullptr) {
|
job->begin = job->begin.subspan(1, job->begin.size() - 1);
|
||||||
auto c = getChildGeq(job->n, job->begin[0]);
|
|
||||||
if (c != nullptr) {
|
if (job->n->partialKeyLen > 0) {
|
||||||
job->n = c;
|
int commonLen = std::min<int>(job->n->partialKeyLen, job->begin.size());
|
||||||
|
int i =
|
||||||
|
longestCommonPrefix(job->n->partialKey(), job->begin.data(), commonLen);
|
||||||
|
if (i < commonLen) {
|
||||||
|
auto c = job->n->partialKey()[i] <=> job->begin[i];
|
||||||
|
if (c > 0) {
|
||||||
return down_left_spine;
|
return down_left_spine;
|
||||||
} else {
|
} else {
|
||||||
job->n = nextSibling(job->n);
|
job->n = nextSibling(job->n);
|
||||||
@@ -3074,44 +3099,24 @@ CheckJob::continuation begin(CheckJob *job) {
|
|||||||
return down_left_spine;
|
return down_left_spine;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (commonLen == job->n->partialKeyLen) {
|
||||||
job->n = child;
|
// partial key matches
|
||||||
job->begin = job->begin.subspan(1, job->begin.size() - 1);
|
job->begin = job->begin.subspan(commonLen, job->begin.size() - commonLen);
|
||||||
|
} else if (job->n->partialKeyLen > int(job->begin.size())) {
|
||||||
if (job->n->partialKeyLen > 0) {
|
// n is the first physical node greater than remaining, and there's no
|
||||||
int commonLen = std::min<int>(job->n->partialKeyLen, job->begin.size());
|
// eq node
|
||||||
int i = longestCommonPrefix(job->n->partialKey(), job->begin.data(),
|
return down_left_spine;
|
||||||
commonLen);
|
|
||||||
if (i < commonLen) {
|
|
||||||
auto c = job->n->partialKey()[i] <=> job->begin[i];
|
|
||||||
if (c > 0) {
|
|
||||||
return down_left_spine;
|
|
||||||
} else {
|
|
||||||
job->n = nextSibling(job->n);
|
|
||||||
if (job->n == nullptr) {
|
|
||||||
job->setResult(true);
|
|
||||||
return nullptr; // Done
|
|
||||||
}
|
|
||||||
return down_left_spine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (commonLen == job->n->partialKeyLen) {
|
|
||||||
// partial key matches
|
|
||||||
job->begin =
|
|
||||||
job->begin.subspan(commonLen, job->begin.size() - commonLen);
|
|
||||||
} else if (job->n->partialKeyLen > int(job->begin.size())) {
|
|
||||||
// n is the first physical node greater than remaining, and there's no
|
|
||||||
// eq node
|
|
||||||
return down_left_spine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxV <= job->readVersion) {
|
|
||||||
++job->tls->point_read_short_circuit_accum;
|
|
||||||
job->setResult(true);
|
|
||||||
return nullptr; // Done
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxV <= job->readVersion) {
|
||||||
|
++job->tls->point_read_short_circuit_accum;
|
||||||
|
job->setResult(true);
|
||||||
|
return nullptr; // Done
|
||||||
|
}
|
||||||
|
|
||||||
|
++job->tls->point_read_iterations_accum;
|
||||||
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckJob::continuation down_left_spine(CheckJob *job) {
|
CheckJob::continuation down_left_spine(CheckJob *job) {
|
||||||
|
Reference in New Issue
Block a user