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