diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 5536608..7828817 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -2933,6 +2933,7 @@ struct CheckJob { Node *n; std::span begin; + InternalVersionT maxV; std::span end; // range read only std::span remaining; // range read only Node *child; // range read only @@ -3013,7 +3014,8 @@ void begin(CheckJob *job, CheckContext *context) { MUSTTAIL return complete(job, context); } - auto taggedChild = getChild(job->n, job->begin[0]); + auto [taggedChild, maxV] = getChildAndMaxVersion(job->n, job->begin[0]); + job->maxV = maxV; Node *child = taggedChild; if (child == nullptr) [[unlikely]] { auto c = getChildGeq(job->n, job->begin[0]); @@ -3072,6 +3074,12 @@ template void iter(CheckJob *job, CheckContext *context) { ++context->tls->point_read_iterations_accum; + if (job->maxV <= job->readVersion) { + job->setResult(true); + ++context->tls->point_read_short_circuit_accum; + MUSTTAIL return complete(job, context); + } + if (job->begin.size() == 0) [[unlikely]] { if (n->entryPresent) { job->setResult(n->entry.pointVersion <= job->readVersion); @@ -3083,7 +3091,8 @@ template void iter(CheckJob *job, CheckContext *context) { MUSTTAIL return keepGoing(job, context); } - auto taggedChild = getChild(n, job->begin[0]); + auto [taggedChild, maxV] = getChildAndMaxVersion(n, job->begin[0]); + job->maxV = maxV; Node *child = taggedChild; if (child == nullptr) [[unlikely]] { auto c = getChildGeq(n, job->begin[0]); @@ -3141,7 +3150,8 @@ void begin(CheckJob *job, CheckContext *context) { // There's no way to encode a prefix read of "" assert(job->begin.size() > 0); - auto taggedChild = getChild(job->n, job->begin[0]); + auto [taggedChild, maxV] = getChildAndMaxVersion(job->n, job->begin[0]); + job->maxV = maxV; Node *child = taggedChild; if (child == nullptr) [[unlikely]] { auto c = getChildGeq(job->n, job->begin[0]); @@ -3194,7 +3204,7 @@ template void iter(CheckJob *job, CheckContext *context) { // n is the first physical node greater than remaining, and there's no // eq node. All physical nodes that start with prefix are reachable from // n. - if (maxVersion(n) > job->readVersion) { + if (job->maxV > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } @@ -3205,12 +3215,19 @@ template void iter(CheckJob *job, CheckContext *context) { ++context->tls->prefix_read_iterations_accum; - if (job->begin.size() == 0) [[unlikely]] { - job->setResult(maxVersion(job->n) <= job->readVersion); + if (job->maxV <= job->readVersion) { + job->setResult(true); + ++context->tls->prefix_read_short_circuit_accum; MUSTTAIL return complete(job, context); } - auto taggedChild = getChild(n, job->begin[0]); + if (job->begin.size() == 0) [[unlikely]] { + job->setResult(job->maxV <= job->readVersion); + MUSTTAIL return complete(job, context); + } + + auto [taggedChild, maxV] = getChildAndMaxVersion(n, job->begin[0]); + job->maxV = maxV; Node *child = taggedChild; if (child == nullptr) [[unlikely]] { auto c = getChildGeq(n, job->begin[0]);