diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 6ce57cf..444c75b 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -3312,16 +3312,16 @@ struct Job { } void init(const ConflictSet::ReadRange *read, ConflictSet::Result *result, - Node *root, int64_t oldestVersionFullPrecision); + IteratorBase root, int64_t oldestVersionFullPrecision); - Node *n; + IteratorBase n; TrivialSpan begin; InternalVersionT maxV; - TrivialSpan end; // range read only - TrivialSpan remaining; // range read only - Node *child; // range read only - int lcp; // range read only - Node *commonPrefixNode; // range read only + TrivialSpan end; // range read only + TrivialSpan remaining; // range read only + IteratorBase child; // range read only + int lcp; // range read only + IteratorBase commonPrefixNode; // range read only InternalVersionT readVersion; ConflictSet::Result *result; Continuation continuation; @@ -3333,7 +3333,7 @@ struct Job { struct Context { int count; int64_t oldestVersionFullPrecision; - Node *root; + IteratorBase root; const ConflictSet::ReadRange *queries; ConflictSet::Result *results; int64_t started; @@ -3371,13 +3371,12 @@ static Continuation downLeftSpineTable[] = { template PRESERVE_NONE void down_left_spine(Job *job, Context *context) { - assert(job->n->getType() == NodeT::kType); - NodeT *n = static_cast(job->n); - if (n->entryPresent) { - job->setResult(n->entry.rangeVersion <= job->readVersion); + Iterator n = job->n.as(); + if (n.entryPresent()) { + job->setResult(n.getEntry().rangeVersion <= job->readVersion); MUSTTAIL return complete(job, context); } - auto child = getFirstChild(n); + auto child = n.getFirstChild(); job->n = child; job->continuation = downLeftSpineTable[child.getType()]; MUSTTAIL return keepGoing(job, context); @@ -3396,17 +3395,17 @@ void begin(Job *job, Context *context) { ++context->readContext.point_read_accum; if (job->begin.size() == 0) [[unlikely]] { // We don't erase the root - assert(job->n->entryPresent); - job->setResult(job->n->entry.pointVersion <= job->readVersion); + assert(job->n.entryPresent()); + job->setResult(job->n.getEntry().pointVersion <= job->readVersion); MUSTTAIL return complete(job, context); } - auto [taggedChild, maxV] = getChildAndMaxVersion(job->n, job->begin[0]); + auto [taggedChild, maxV] = job->n.getChildAndMaxVersion(job->begin[0]); job->maxV = maxV; - Node *child = taggedChild; - if (child == nullptr) [[unlikely]] { - auto c = getChildGeq(job->n, job->begin[0]); - if (c != nullptr) { + IteratorBase child = taggedChild; + if (!child.valid()) [[unlikely]] { + auto c = job->n.getChildGeq(job->begin[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); @@ -3423,21 +3422,22 @@ void begin(Job *job, Context *context) { template void iter(Job *job, Context *context) { - assert(NodeT::kType == job->n->getType()); - NodeT *n = static_cast(job->n); + Iterator n = job->n.as(); job->begin = job->begin.subspan(1, job->begin.size() - 1); - if (n->partialKeyLen > 0) { - int commonLen = std::min(n->partialKeyLen, job->begin.size()); - int i = longestCommonPrefix(n->partialKey(), job->begin.data(), commonLen); + auto partialKey = n.partialKey(); + if (partialKey.size() > 0) { + int commonLen = std::min(partialKey.size(), job->begin.size()); + int i = + longestCommonPrefix(partialKey.data(), job->begin.data(), commonLen); if (i < commonLen) { - auto c = n->partialKey()[i] <=> job->begin[i]; + auto c = partialKey[i] <=> job->begin[i]; if (c > 0) { MUSTTAIL return down_left_spine(job, context); } else { - auto s = nextSibling(n); + auto s = n.nextSibling(); job->n = s; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -3445,10 +3445,10 @@ template void iter(Job *job, Context *context) { MUSTTAIL return keepGoing(job, context); } } - if (commonLen == n->partialKeyLen) { + if (commonLen == partialKey.size()) { // partial key matches job->begin = job->begin.subspan(commonLen, job->begin.size() - commonLen); - } else if (n->partialKeyLen > job->begin.size()) [[unlikely]] { + } else if (partialKey.size() > job->begin.size()) [[unlikely]] { // n is the first physical node greater than remaining, and there's no // eq node MUSTTAIL return down_left_spine(job, context); @@ -3464,33 +3464,33 @@ template void iter(Job *job, Context *context) { ++context->readContext.point_read_iterations_accum; if (job->begin.size() == 0) { - if (n->entryPresent) { - job->setResult(n->entry.pointVersion <= job->readVersion); + if (n.entryPresent()) { + job->setResult(n.getEntry().pointVersion <= job->readVersion); MUSTTAIL return complete(job, context); } - auto c = getFirstChild(n); + auto c = n.getFirstChild(); job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } - auto [taggedChild, maxV] = getChildAndMaxVersion(n, job->begin[0]); + auto [taggedChild, maxV] = n.getChildAndMaxVersion(job->begin[0]); job->maxV = maxV; - Node *child = taggedChild; - if (child == nullptr) { - auto c = getChildGeq(n, job->begin[0]); - if (c != nullptr) { + IteratorBase child = taggedChild; + if (!child.valid()) { + auto c = n.getChildGeq(job->begin[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } - job->continuation = downLeftSpineTable[c->getType()]; + job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } } @@ -3516,12 +3516,12 @@ void begin(Job *job, Context *context) { // There's no way to encode a prefix read of "" assert(job->begin.size() > 0); - auto [taggedChild, maxV] = getChildAndMaxVersion(job->n, job->begin[0]); + auto [taggedChild, maxV] = job->n.getChildAndMaxVersion(job->begin[0]); job->maxV = maxV; - Node *child = taggedChild; - if (child == nullptr) [[unlikely]] { - auto c = getChildGeq(job->n, job->begin[0]); - if (c != nullptr) { + IteratorBase child = taggedChild; + if (!child.valid()) [[unlikely]] { + auto c = job->n.getChildGeq(job->begin[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); @@ -3538,21 +3538,22 @@ void begin(Job *job, Context *context) { template void iter(Job *job, Context *context) { - assert(NodeT::kType == job->n->getType()); - NodeT *n = static_cast(job->n); + Iterator n = job->n.as(); job->begin = job->begin.subspan(1, job->begin.size() - 1); - if (n->partialKeyLen > 0) { - int commonLen = std::min(n->partialKeyLen, job->begin.size()); - int i = longestCommonPrefix(n->partialKey(), job->begin.data(), commonLen); + auto partialKey = n.partialKey(); + if (partialKey.size() > 0) { + int commonLen = std::min(partialKey.size(), job->begin.size()); + int i = + longestCommonPrefix(partialKey.data(), job->begin.data(), commonLen); if (i < commonLen) [[unlikely]] { - auto c = n->partialKey()[i] <=> job->begin[i]; + auto c = partialKey[i] <=> job->begin[i]; if (c > 0) { MUSTTAIL return down_left_spine(job, context); } else { - auto c = nextSibling(n); + auto c = n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -3560,10 +3561,10 @@ template void iter(Job *job, Context *context) { MUSTTAIL return keepGoing(job, context); } } - if (commonLen == n->partialKeyLen) { + if (commonLen == partialKey.size()) { // partial key matches job->begin = job->begin.subspan(commonLen, job->begin.size() - commonLen); - } else if (n->partialKeyLen > job->begin.size()) [[unlikely]] { + } else if (partialKey.size() > job->begin.size()) [[unlikely]] { // 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. @@ -3588,19 +3589,19 @@ template void iter(Job *job, Context *context) { MUSTTAIL return complete(job, context); } - auto [taggedChild, maxV] = getChildAndMaxVersion(n, job->begin[0]); + auto [taggedChild, maxV] = n.getChildAndMaxVersion(job->begin[0]); job->maxV = maxV; - Node *child = taggedChild; - if (child == nullptr) [[unlikely]] { - auto c = getChildGeq(n, job->begin[0]); - if (c != nullptr) { + IteratorBase child = taggedChild; + if (!child.valid()) [[unlikely]] { + auto c = n.getChildGeq(job->begin[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -3674,14 +3675,14 @@ PRESERVE_NONE void begin(Job *job, Context *context) { job->remaining = job->begin.subspan(0, job->lcp); if (job->remaining.size() == 0) { - MUSTTAIL return doneCommonPrefixIterTable[job->n->getType()](job, context); + MUSTTAIL return doneCommonPrefixIterTable[job->n.getType()](job, context); } - auto [c, maxV] = getChildAndMaxVersion(job->n, job->remaining[0]); + auto [c, maxV] = job->n.getChildAndMaxVersion(job->remaining[0]); job->maxV = maxV; job->child = c; - if (job->child == nullptr) { - MUSTTAIL return doneCommonPrefixIterTable[job->n->getType()](job, context); + if (!job->child.valid()) { + MUSTTAIL return doneCommonPrefixIterTable[job->n.getType()](job, context); } job->continuation = commonPrefixIterTable[c.getType()]; @@ -3691,22 +3692,20 @@ PRESERVE_NONE void begin(Job *job, Context *context) { // Advance down common prefix, but stay on a physical path in the tree template void common_prefix_iter(Job *job, Context *context) { - assert(NodeT::kType == job->child->getType()); - NodeT *child = static_cast(job->child); + Iterator child = job->child.as(); - if (child->partialKeyLen > 0) { - int cl = std::min(child->partialKeyLen, job->remaining.size() - 1); + auto partialKey = child.partialKey(); + if (partialKey.size() > 0) { + int cl = std::min(partialKey.size(), job->remaining.size() - 1); int i = - longestCommonPrefix(child->partialKey(), job->remaining.data() + 1, cl); - if (i != child->partialKeyLen) { - MUSTTAIL return doneCommonPrefixIterTable[job->n->getType()](job, - context); + longestCommonPrefix(partialKey.data(), job->remaining.data() + 1, cl); + if (i != partialKey.size()) { + MUSTTAIL return doneCommonPrefixIterTable[job->n.getType()](job, context); } } job->n = child; - job->remaining = job->remaining.subspan(1 + child->partialKeyLen, - job->remaining.size() - - (1 + child->partialKeyLen)); + job->remaining = job->remaining.subspan( + 1 + partialKey.size(), job->remaining.size() - (1 + partialKey.size())); if (job->maxV <= job->readVersion) { job->setResult(true); @@ -3720,10 +3719,10 @@ template void common_prefix_iter(Job *job, Context *context) { MUSTTAIL return done_common_prefix_iter(job, context); } - auto [c, maxV] = getChildAndMaxVersion(child, job->remaining[0]); + auto [c, maxV] = child.getChildAndMaxVersion(job->remaining[0]); job->maxV = maxV; job->child = c; - if (job->child == nullptr) { + if (!job->child.valid()) { MUSTTAIL return done_common_prefix_iter(job, context); } @@ -3733,12 +3732,11 @@ template void common_prefix_iter(Job *job, Context *context) { template PRESERVE_NONE void done_common_prefix_iter(Job *job, Context *context) { - assert(NodeT::kType == job->n->getType()); - NodeT *n = static_cast(job->n); + Iterator n = job->n.as(); { Arena arena; - assert(getSearchPath(arena, n) <=> + assert(n.getSearchPath(arena) <=> job->begin.subspan(0, job->lcp - job->remaining.size()) == 0); } @@ -3754,13 +3752,13 @@ PRESERVE_NONE void done_common_prefix_iter(Job *job, Context *context) { if (job->lcp == job->begin.size()) { job->remaining = job->end; if (job->lcp == 0) { - if (n->entryPresent && n->entry.pointVersion > job->readVersion) { + if (n.entryPresent() && n.getEntry().pointVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } - if (!checkMaxBetweenExclusive(n, -1, job->remaining[0], job->readVersion, - &context->readContext)) { + if (!checkMaxBetweenExclusive(n.escapeHatch(), -1, job->remaining[0], + job->readVersion, &context->readContext)) { job->setResult(false); MUSTTAIL return complete(job, context); } @@ -3769,18 +3767,18 @@ PRESERVE_NONE void done_common_prefix_iter(Job *job, Context *context) { // This is a hack --job->lcp; - auto cAndV = getChildAndMaxVersion(n, job->remaining[0]); - Node *child = cAndV.child; - if (child == nullptr) { - auto c = getChildGeq(n, job->remaining[0]); - if (c != nullptr) { + auto cAndV = n.getChildAndMaxVersion(job->remaining[0]); + IteratorBase child = cAndV.child; + if (!child.valid()) { + auto c = n.getChildGeq(job->remaining[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -3807,19 +3805,19 @@ PRESERVE_NONE void done_common_prefix_iter(Job *job, Context *context) { job->remaining = job->begin; - auto [c, maxV] = getChildAndMaxVersion(n, job->remaining[0]); + auto [c, maxV] = n.getChildAndMaxVersion(job->remaining[0]); job->maxV = maxV; - Node *child = c; - if (child == nullptr) { - auto c = getChildGeq(n, job->remaining[0]); - if (c != nullptr) { + IteratorBase child = c; + if (!child.valid()) { + auto c = n.getChildGeq(job->remaining[0]); + if (c.valid()) { job->n = c; job->continuation = leftSideDownLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { MUSTTAIL return done_left_side_iter(job, context); } job->continuation = leftSideDownLeftSpineTable[c.getType()]; @@ -3836,24 +3834,24 @@ PRESERVE_NONE void done_common_prefix_iter(Job *job, Context *context) { // that are >= key is <= readVersion template PRESERVE_NONE void left_side_iter(Job *job, Context *context) { - assert(NodeT::kType == job->n->getType()); - NodeT *n = static_cast(job->n); + Iterator n = job->n.as(); job->remaining = job->remaining.subspan(1, job->remaining.size() - 1); - if (n->partialKeyLen > 0) { - int commonLen = std::min(n->partialKeyLen, job->remaining.size()); - int i = - longestCommonPrefix(n->partialKey(), job->remaining.data(), commonLen); + auto partialKey = n.partialKey(); + if (partialKey.size() > 0) { + int commonLen = std::min(partialKey.size(), job->remaining.size()); + int i = longestCommonPrefix(partialKey.data(), job->remaining.data(), + commonLen); if (i < commonLen) { - auto c = n->partialKey()[i] <=> job->remaining[i]; + auto c = partialKey[i] <=> job->remaining[i]; if (c > 0) { - if (n->parent == job->commonPrefixNode) { + if (n.parent() == job->commonPrefixNode) { if (i < job->lcp) { MUSTTAIL return left_side_down_left_spine(job, context); } } - if (n->entryPresent && n->entry.rangeVersion > job->readVersion) { + if (n.entryPresent() && n.getEntry().rangeVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } @@ -3863,21 +3861,21 @@ PRESERVE_NONE void left_side_iter(Job *job, Context *context) { } MUSTTAIL return done_left_side_iter(job, context); } else { - auto c = nextSibling(n); + auto c = n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { MUSTTAIL return done_left_side_iter(job, context); } job->continuation = leftSideDownLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } } - if (commonLen == n->partialKeyLen) { + if (commonLen == partialKey.size()) { // partial key matches job->remaining = job->remaining.subspan(commonLen, job->remaining.size() - commonLen); - } else if (n->partialKeyLen > job->remaining.size()) { - if (n->entryPresent && n->entry.rangeVersion > job->readVersion) { + } else if (partialKey.size() > job->remaining.size()) { + if (n.entryPresent() && n.getEntry().rangeVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } @@ -3901,24 +3899,24 @@ PRESERVE_NONE void left_side_iter(Job *job, Context *context) { MUSTTAIL return complete(job, context); } - if (!checkMaxBetweenExclusive(n, job->remaining[0], 256, job->readVersion, - &context->readContext)) { + if (!checkMaxBetweenExclusive(n.escapeHatch(), job->remaining[0], 256, + job->readVersion, &context->readContext)) { job->setResult(false); MUSTTAIL return complete(job, context); } - auto [c, maxV] = getChildAndMaxVersion(n, job->remaining[0]); + auto [c, maxV] = n.getChildAndMaxVersion(job->remaining[0]); job->maxV = maxV; - Node *child = c; - if (child == nullptr) { - auto c = getChildGeq(n, job->remaining[0]); - if (c != nullptr) { + IteratorBase child = c; + if (!child.valid()) { + auto c = n.getChildGeq(job->remaining[0]); + if (c.valid()) { job->n = c; MUSTTAIL return done_left_side_iter(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { MUSTTAIL return done_left_side_iter(job, context); } job->continuation = leftSideDownLeftSpineTable[c.getType()]; @@ -3936,18 +3934,18 @@ PRESERVE_NONE void done_left_side_iter(Job *job, Context *context) { job->n = job->commonPrefixNode; job->remaining = job->end; - auto cAndV = getChildAndMaxVersion(job->n, job->remaining[0]); - Node *child = cAndV.child; - if (child == nullptr) { - auto c = getChildGeq(job->n, job->remaining[0]); - if (c != nullptr) { + auto cAndV = job->n.getChildAndMaxVersion(job->remaining[0]); + IteratorBase child = cAndV.child; + if (!child.valid()) { + auto c = job->n.getChildGeq(job->remaining[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -3964,17 +3962,16 @@ PRESERVE_NONE void done_left_side_iter(Job *job, Context *context) { template void left_side_down_left_spine(Job *job, Context *context) { - assert(job->n->getType() == NodeT::kType); - NodeT *n = static_cast(job->n); + Iterator n = job->n.as(); - if (n->entryPresent) { - if (n->entry.rangeVersion > job->readVersion) { + if (n.entryPresent()) { + if (n.getEntry().rangeVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } MUSTTAIL return done_left_side_iter(job, context); } - auto c = getFirstChild(n); + auto c = n.getFirstChild(); job->n = c; job->continuation = leftSideDownLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); @@ -3984,33 +3981,33 @@ void left_side_down_left_spine(Job *job, Context *context) { // that are < key is <= readVersion template PRESERVE_NONE void right_side_iter(Job *job, Context *context) { - assert(NodeT::kType == job->n->getType()); - NodeT *n = static_cast(job->n); + Iterator n = job->n.as(); job->remaining = job->remaining.subspan(1, job->remaining.size() - 1); - if (n->partialKeyLen > 0) { - int commonLen = std::min(n->partialKeyLen, job->remaining.size()); - int i = - longestCommonPrefix(n->partialKey(), job->remaining.data(), commonLen); + auto partialKey = n.partialKey(); + if (partialKey.size() > 0) { + int commonLen = std::min(partialKey.size(), job->remaining.size()); + int i = longestCommonPrefix(partialKey.data(), job->remaining.data(), + commonLen); if (i < commonLen) { - auto c = n->partialKey()[i] <=> job->remaining[i]; + auto c = partialKey[i] <=> job->remaining[i]; if (c > 0) { MUSTTAIL return down_left_spine(job, context); } else { - if ((n->parent != job->commonPrefixNode || i >= job->lcp) && - n->entryPresent && n->entry.rangeVersion > job->readVersion) { + if ((n.parent() != job->commonPrefixNode || i >= job->lcp) && + n.entryPresent() && n.getEntry().rangeVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } - if ((n->parent != job->commonPrefixNode || i >= job->lcp) && + if ((n.parent() != job->commonPrefixNode || i >= job->lcp) && job->maxV > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -4018,11 +4015,11 @@ PRESERVE_NONE void right_side_iter(Job *job, Context *context) { MUSTTAIL return keepGoing(job, context); } } - if (commonLen == n->partialKeyLen) { + if (commonLen == partialKey.size()) { // partial key matches job->remaining = job->remaining.subspan(commonLen, job->remaining.size() - commonLen); - } else if (n->partialKeyLen > job->remaining.size()) { + } else if (partialKey.size() > job->remaining.size()) { MUSTTAIL return down_left_spine(job, context); } } @@ -4033,34 +4030,34 @@ PRESERVE_NONE void right_side_iter(Job *job, Context *context) { MUSTTAIL return down_left_spine(job, context); } - if (n->entryPresent && n->entry.pointVersion > job->readVersion) { + if (n.entryPresent() && n.getEntry().pointVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } - if (!checkMaxBetweenExclusive(n, -1, job->remaining[0], job->readVersion, - &context->readContext)) { + if (!checkMaxBetweenExclusive(n.escapeHatch(), -1, job->remaining[0], + job->readVersion, &context->readContext)) { job->setResult(false); MUSTTAIL return complete(job, context); } - if (n->entryPresent && n->entry.rangeVersion > job->readVersion) { + if (n.entryPresent() && n.getEntry().rangeVersion > job->readVersion) { job->setResult(false); MUSTTAIL return complete(job, context); } - auto cAndV = getChildAndMaxVersion(n, job->remaining[0]); - Node *child = cAndV.child; - if (child == nullptr) { - auto c = getChildGeq(n, job->remaining[0]); - if (c != nullptr) { + auto cAndV = n.getChildAndMaxVersion(job->remaining[0]); + IteratorBase child = cAndV.child; + if (!child.valid()) { + auto c = n.getChildGeq(job->remaining[0]); + if (c.valid()) { job->n = c; job->continuation = downLeftSpineTable[c.getType()]; MUSTTAIL return keepGoing(job, context); } else { - auto c = nextSibling(job->n); + auto c = job->n.nextSibling(); job->n = c; - if (job->n == nullptr) { + if (!job->n.valid()) { job->setResult(true); MUSTTAIL return complete(job, context); } @@ -4078,7 +4075,7 @@ PRESERVE_NONE void right_side_iter(Job *job, Context *context) { } // namespace range_read_state_machine void Job::init(const ConflictSet::ReadRange *read, ConflictSet::Result *result, - Node *root, int64_t oldestVersionFullPrecision) { + IteratorBase root, int64_t oldestVersionFullPrecision) { auto begin = TrivialSpan(read->begin.p, read->begin.len); auto end = TrivialSpan(read->end.p, read->end.len); if (read->readVersion < oldestVersionFullPrecision) [[unlikely]] { @@ -5054,13 +5051,14 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { check::Job inProgress[kConcurrent]; context.count = count; context.oldestVersionFullPrecision = oldestVersionFullPrecision; - context.root = rootParent->children[0]; + context.root = IteratorBase{rootParent->children[0]}; context.queries = reads; context.results = result; int64_t started = std::min(kConcurrent, count); context.started = started; for (int i = 0; i < started; i++) { - inProgress[i].init(reads + i, result + i, rootParent->children[0], + inProgress[i].init(reads + i, result + i, + IteratorBase{rootParent->children[0]}, oldestVersionFullPrecision); } for (int i = 0; i < started - 1; i++) {