Convert interleaved checks to IteratorBase
This commit is contained in:
324
ConflictSet.cpp
324
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 <class NodeT>
|
||||
PRESERVE_NONE void down_left_spine(Job *job, Context *context) {
|
||||
assert(job->n->getType() == NodeT::kType);
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
if (n->entryPresent) {
|
||||
job->setResult(n->entry.rangeVersion <= job->readVersion);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
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 <class NodeT> void iter(Job *job, Context *context) {
|
||||
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
job->begin = job->begin.subspan(1, job->begin.size() - 1);
|
||||
|
||||
if (n->partialKeyLen > 0) {
|
||||
int commonLen = std::min<int>(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<int>(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<NodeT>(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 <class NodeT> 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<NodeT>(job, context);
|
||||
@@ -3464,33 +3464,33 @@ template <class NodeT> 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 <class NodeT> void iter(Job *job, Context *context) {
|
||||
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
job->begin = job->begin.subspan(1, job->begin.size() - 1);
|
||||
|
||||
if (n->partialKeyLen > 0) {
|
||||
int commonLen = std::min<int>(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<int>(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<NodeT>(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 <class NodeT> 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 <class NodeT> 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 <class NodeT> void common_prefix_iter(Job *job, Context *context) {
|
||||
|
||||
assert(NodeT::kType == job->child->getType());
|
||||
NodeT *child = static_cast<NodeT *>(job->child);
|
||||
Iterator<NodeT> child = job->child.as<NodeT>();
|
||||
|
||||
if (child->partialKeyLen > 0) {
|
||||
int cl = std::min<int>(child->partialKeyLen, job->remaining.size() - 1);
|
||||
auto partialKey = child.partialKey();
|
||||
if (partialKey.size() > 0) {
|
||||
int cl = std::min<int>(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 <class NodeT> void common_prefix_iter(Job *job, Context *context) {
|
||||
MUSTTAIL return done_common_prefix_iter<NodeT>(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<NodeT>(job, context);
|
||||
}
|
||||
|
||||
@@ -3733,12 +3732,11 @@ template <class NodeT> void common_prefix_iter(Job *job, Context *context) {
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void done_common_prefix_iter(Job *job, Context *context) {
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
|
||||
{
|
||||
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 <class NodeT>
|
||||
PRESERVE_NONE void left_side_iter(Job *job, Context *context) {
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
|
||||
job->remaining = job->remaining.subspan(1, job->remaining.size() - 1);
|
||||
|
||||
if (n->partialKeyLen > 0) {
|
||||
int commonLen = std::min<int>(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<int>(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<NodeT>(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 <class NodeT>
|
||||
void left_side_down_left_spine(Job *job, Context *context) {
|
||||
assert(job->n->getType() == NodeT::kType);
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
|
||||
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 <class NodeT>
|
||||
PRESERVE_NONE void right_side_iter(Job *job, Context *context) {
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
Iterator<NodeT> n = job->n.as<NodeT>();
|
||||
|
||||
job->remaining = job->remaining.subspan(1, job->remaining.size() - 1);
|
||||
|
||||
if (n->partialKeyLen > 0) {
|
||||
int commonLen = std::min<int>(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<int>(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<NodeT>(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<NodeT>(job, context);
|
||||
}
|
||||
}
|
||||
@@ -4033,34 +4030,34 @@ PRESERVE_NONE void right_side_iter(Job *job, Context *context) {
|
||||
MUSTTAIL return down_left_spine<NodeT>(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++) {
|
||||
|
||||
Reference in New Issue
Block a user