Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5452c0f7d | ||
|
|
66fc526a55 | ||
|
|
21f08b9f88 | ||
|
|
10c2f06199 | ||
|
|
5cf04e9718 | ||
|
|
707b220fbc |
+189
-127
@@ -1193,9 +1193,9 @@ ChildAndMaxVersion getChildAndMaxVersion(Node *self, uint8_t index) {
|
||||
}
|
||||
}
|
||||
|
||||
Node *getChildGeq(Node0 *, int) { return nullptr; }
|
||||
TaggedNodePointer getChildGeq(Node0 *, int) { return nullptr; }
|
||||
|
||||
Node *getChildGeq(Node3 *n, int child) {
|
||||
TaggedNodePointer getChildGeq(Node3 *n, int child) {
|
||||
assume(n->numChildren >= 1);
|
||||
assume(n->numChildren <= 3);
|
||||
for (int i = 0; i < n->numChildren; ++i) {
|
||||
@@ -1206,7 +1206,7 @@ Node *getChildGeq(Node3 *n, int child) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Node *getChildGeq(Node16 *self, int child) {
|
||||
TaggedNodePointer getChildGeq(Node16 *self, int child) {
|
||||
if (child > 255) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1249,14 +1249,14 @@ Node *getChildGeq(Node16 *self, int child) {
|
||||
#endif
|
||||
}
|
||||
|
||||
Node *getChildGeq(Node48 *self, int child) {
|
||||
TaggedNodePointer getChildGeq(Node48 *self, int child) {
|
||||
int c = self->bitSet.firstSetGeq(child);
|
||||
if (c < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return self->children[self->index[c]];
|
||||
}
|
||||
Node *getChildGeq(Node256 *self, int child) {
|
||||
TaggedNodePointer getChildGeq(Node256 *self, int child) {
|
||||
int c = self->bitSet.firstSetGeq(child);
|
||||
if (c < 0) {
|
||||
return nullptr;
|
||||
@@ -1264,7 +1264,7 @@ Node *getChildGeq(Node256 *self, int child) {
|
||||
return self->children[c];
|
||||
}
|
||||
|
||||
Node *getChildGeq(Node *self, int child) {
|
||||
TaggedNodePointer getChildGeq(Node *self, int child) {
|
||||
switch (self->getType()) {
|
||||
case Type_Node0:
|
||||
return getChildGeq(static_cast<Node0 *>(self), child);
|
||||
@@ -1281,27 +1281,62 @@ Node *getChildGeq(Node *self, int child) {
|
||||
}
|
||||
}
|
||||
|
||||
Node *getFirstChild(Node0 *) { return nullptr; }
|
||||
Node *getFirstChild(Node3 *self) {
|
||||
return self->numChildren == 0 ? nullptr : self->children[0];
|
||||
}
|
||||
Node *getFirstChild(Node16 *self) {
|
||||
return self->numChildren == 0 ? nullptr : self->children[0];
|
||||
}
|
||||
Node *getFirstChild(Node48 *self) {
|
||||
int index = self->index[self->bitSet.firstSetGeq(0)];
|
||||
return index < 0 ? nullptr : self->children[index];
|
||||
}
|
||||
Node *getFirstChild(Node256 *self) {
|
||||
return self->children[self->bitSet.firstSetGeq(0)];
|
||||
}
|
||||
|
||||
Node *getFirstChild(Node *self) {
|
||||
// Only require that the node-specific overloads are covered
|
||||
// GCOVR_EXCL_START
|
||||
switch (self->getType()) {
|
||||
case Type_Node0:
|
||||
return getFirstChild(static_cast<Node0 *>(self));
|
||||
case Type_Node3:
|
||||
return getFirstChild(static_cast<Node3 *>(self));
|
||||
case Type_Node16:
|
||||
return getFirstChild(static_cast<Node16 *>(self));
|
||||
case Type_Node48:
|
||||
return getFirstChild(static_cast<Node48 *>(self));
|
||||
case Type_Node256:
|
||||
return getFirstChild(static_cast<Node256 *>(self));
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
// GCOVR_EXCL_STOP
|
||||
}
|
||||
|
||||
// Precondition: self has a child
|
||||
Node *getFirstChildExists(Node3 *self) {
|
||||
TaggedNodePointer getFirstChildExists(Node3 *self) {
|
||||
assert(self->numChildren > 0);
|
||||
return self->children[0];
|
||||
}
|
||||
// Precondition: self has a child
|
||||
Node *getFirstChildExists(Node16 *self) {
|
||||
TaggedNodePointer getFirstChildExists(Node16 *self) {
|
||||
assert(self->numChildren > 0);
|
||||
return self->children[0];
|
||||
}
|
||||
// Precondition: self has a child
|
||||
Node *getFirstChildExists(Node48 *self) {
|
||||
TaggedNodePointer getFirstChildExists(Node48 *self) {
|
||||
return self->children[self->index[self->bitSet.firstSetGeq(0)]];
|
||||
}
|
||||
// Precondition: self has a child
|
||||
Node *getFirstChildExists(Node256 *self) {
|
||||
TaggedNodePointer getFirstChildExists(Node256 *self) {
|
||||
return self->children[self->bitSet.firstSetGeq(0)];
|
||||
}
|
||||
|
||||
// Precondition: self has a child
|
||||
Node *getFirstChildExists(Node *self) {
|
||||
TaggedNodePointer getFirstChildExists(Node *self) {
|
||||
// Only require that the node-specific overloads are covered
|
||||
// GCOVR_EXCL_START
|
||||
switch (self->getType()) {
|
||||
@@ -1559,36 +1594,45 @@ TaggedNodePointer &getOrCreateChild(TaggedNodePointer &self,
|
||||
}
|
||||
|
||||
Node *nextPhysical(Node *node) {
|
||||
int index = -1;
|
||||
auto nextChild = getFirstChild(node);
|
||||
if (nextChild != nullptr) {
|
||||
return nextChild;
|
||||
}
|
||||
for (;;) {
|
||||
auto nextChild = getChildGeq(node, index + 1);
|
||||
if (nextChild != nullptr) {
|
||||
return nextChild;
|
||||
}
|
||||
index = node->parentsIndex;
|
||||
int index = node->parentsIndex;
|
||||
node = node->parent;
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto nextChild = getChildGeq(node, index + 1);
|
||||
if (nextChild != nullptr) {
|
||||
return nextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Node *nextLogical(Node *node) {
|
||||
int index = -1;
|
||||
auto nextChild = getFirstChild(node);
|
||||
if (nextChild != nullptr) {
|
||||
node = nextChild;
|
||||
goto downLeftSpine;
|
||||
}
|
||||
for (;;) {
|
||||
auto nextChild = getChildGeq(node, index + 1);
|
||||
if (nextChild != nullptr) {
|
||||
for (node = nextChild; !node->entryPresent;
|
||||
node = getFirstChildExists(node)) {
|
||||
}
|
||||
return node;
|
||||
}
|
||||
index = node->parentsIndex;
|
||||
int index = node->parentsIndex;
|
||||
node = node->parent;
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto nextChild = getChildGeq(node, index + 1);
|
||||
if (nextChild != nullptr) {
|
||||
node = nextChild;
|
||||
goto downLeftSpine;
|
||||
}
|
||||
}
|
||||
downLeftSpine:
|
||||
for (; !node->entryPresent; node = getFirstChildExists(node)) {
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
// Invalidates `self`, replacing it with a node of at least capacity.
|
||||
@@ -1977,7 +2021,7 @@ Node *erase(Node *self, WriteContext *writeContext, ConflictSet::Impl *impl,
|
||||
return result;
|
||||
}
|
||||
|
||||
Node *nextSibling(Node *node) {
|
||||
TaggedNodePointer nextSibling(Node *node) {
|
||||
for (;;) {
|
||||
if (node->parent == nullptr) {
|
||||
return nullptr;
|
||||
@@ -3053,13 +3097,25 @@ PRESERVE_NONE void complete(CheckJob *job, CheckContext *context) {
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void down_left_spine(CheckJob *job, CheckContext *context);
|
||||
|
||||
static Continuation downLeftSpineTable[] = {
|
||||
down_left_spine<Node0>, down_left_spine<Node3>, down_left_spine<Node16>,
|
||||
down_left_spine<Node48>, down_left_spine<Node256>};
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void down_left_spine(CheckJob *job, CheckContext *context) {
|
||||
if (job->n->entryPresent) {
|
||||
job->setResult(job->n->entry.rangeVersion <= job->readVersion);
|
||||
assert(job->n->getType() == NodeT::kType);
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
if (n->entryPresent) {
|
||||
job->setResult(n->entry.rangeVersion <= job->readVersion);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->n = getFirstChildExists(job->n);
|
||||
auto child = getFirstChildExists(n);
|
||||
job->n = child;
|
||||
__builtin_prefetch(job->n);
|
||||
job->continuation = downLeftSpineTable[child.getType()];
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
@@ -3092,7 +3148,7 @@ void begin(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(job->n, job->begin[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
@@ -3119,15 +3175,15 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
if (i < commonLen) [[unlikely]] {
|
||||
auto c = n->partialKey()[i] <=> job->begin[i];
|
||||
if (c > 0) {
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return down_left_spine(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(n);
|
||||
auto s = nextSibling(n);
|
||||
job->n = s;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[s.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3138,8 +3194,7 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
} else if (n->partialKeyLen > int(job->begin.size())) [[unlikely]] {
|
||||
// n is the first physical node greater than remaining, and there's no
|
||||
// eq node
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return down_left_spine(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3156,8 +3211,9 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
job->setResult(n->entry.pointVersion <= job->readVersion);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->n = getFirstChildExists(n);
|
||||
job->continuation = down_left_spine;
|
||||
auto c = getFirstChildExists(n);
|
||||
job->n = c;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3169,16 +3225,17 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(n, job->begin[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c->getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3216,7 +3273,7 @@ void begin(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(job->n, job->begin[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
@@ -3243,15 +3300,15 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
if (i < commonLen) [[unlikely]] {
|
||||
auto c = n->partialKey()[i] <=> job->begin[i];
|
||||
if (c > 0) {
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return down_left_spine(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(n);
|
||||
auto c = nextSibling(n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3267,8 +3324,7 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return down_left_spine(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3292,16 +3348,17 @@ template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(n, job->begin[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3336,8 +3393,14 @@ static Continuation doneCommonPrefixIterTable[] = {
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void left_side_iter(CheckJob *, CheckContext *);
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void left_side_down_left_spine(CheckJob *, CheckContext *);
|
||||
|
||||
static Continuation leftSideDownLeftSpineTable[] = {
|
||||
left_side_down_left_spine<Node0>, left_side_down_left_spine<Node3>,
|
||||
left_side_down_left_spine<Node16>, left_side_down_left_spine<Node48>,
|
||||
left_side_down_left_spine<Node256>};
|
||||
|
||||
PRESERVE_NONE void done_left_side_iter(CheckJob *, CheckContext *);
|
||||
|
||||
static Continuation leftSideIterTable[] = {
|
||||
@@ -3356,32 +3419,28 @@ PRESERVE_NONE void begin(CheckJob *job, CheckContext *context) {
|
||||
std::min(job->begin.size(), job->end.size()));
|
||||
if (job->lcp == int(job->begin.size()) &&
|
||||
job->end.size() == job->begin.size() + 1 && job->end.back() == 0) {
|
||||
job->continuation = check_point_read_state_machine::begin;
|
||||
// Call directly since we have nothing to prefetch
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return check_point_read_state_machine::begin(job, context);
|
||||
}
|
||||
if (job->lcp == int(job->begin.size() - 1) &&
|
||||
job->end.size() == job->begin.size() &&
|
||||
int(job->begin.back()) + 1 == int(job->end.back())) {
|
||||
job->continuation = check_prefix_read_state_machine::begin;
|
||||
// Call directly since we have nothing to prefetch
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return check_prefix_read_state_machine::begin(job, context);
|
||||
}
|
||||
|
||||
++context->readContext.range_read_accum;
|
||||
job->remaining = job->begin.subspan(0, job->lcp);
|
||||
|
||||
if (job->remaining.size() == 0) {
|
||||
job->continuation = doneCommonPrefixIterTable[job->n->getType()];
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return doneCommonPrefixIterTable[job->n->getType()](job, context);
|
||||
}
|
||||
|
||||
auto [c, maxV] = getChildAndMaxVersion(job->n, job->remaining[0]);
|
||||
job->maxV = maxV;
|
||||
job->child = c;
|
||||
if (job->child == nullptr) {
|
||||
job->continuation = doneCommonPrefixIterTable[job->n->getType()];
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return doneCommonPrefixIterTable[job->n->getType()](job, context);
|
||||
}
|
||||
|
||||
job->continuation = commonPrefixIterTable[c.getType()];
|
||||
@@ -3401,8 +3460,8 @@ void common_prefix_iter(CheckJob *job, CheckContext *context) {
|
||||
int i =
|
||||
longestCommonPrefix(child->partialKey(), job->remaining.data() + 1, cl);
|
||||
if (i != child->partialKeyLen) {
|
||||
job->continuation = doneCommonPrefixIterTable[job->n->getType()];
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return doneCommonPrefixIterTable[job->n->getType()](job,
|
||||
context);
|
||||
}
|
||||
}
|
||||
job->n = child;
|
||||
@@ -3419,16 +3478,14 @@ void common_prefix_iter(CheckJob *job, CheckContext *context) {
|
||||
++context->readContext.range_read_iterations_accum;
|
||||
|
||||
if (job->remaining.size() == 0) {
|
||||
job->continuation = done_common_prefix_iter<NodeT>;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_common_prefix_iter<NodeT>(job, context);
|
||||
}
|
||||
|
||||
auto [c, maxV] = getChildAndMaxVersion(child, job->remaining[0]);
|
||||
job->maxV = maxV;
|
||||
job->child = c;
|
||||
if (job->child == nullptr) {
|
||||
job->continuation = done_common_prefix_iter<NodeT>;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_common_prefix_iter<NodeT>(job, context);
|
||||
}
|
||||
|
||||
job->continuation = commonPrefixIterTable[c.getType()];
|
||||
@@ -3481,16 +3538,17 @@ PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
auto c = getChildGeq(n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return downLeftSpineTable[c.getType()](job, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3519,16 +3577,16 @@ PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
auto c = getChildGeq(n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = left_side_down_left_spine;
|
||||
job->continuation = leftSideDownLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
}
|
||||
job->continuation = left_side_down_left_spine;
|
||||
job->continuation = leftSideDownLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3558,8 +3616,7 @@ PRESERVE_NONE void left_side_iter(CheckJob *job, CheckContext *context) {
|
||||
if (c > 0) {
|
||||
if (n->parent == job->commonPrefixNode) {
|
||||
if (i < job->lcp) {
|
||||
job->continuation = left_side_down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return left_side_down_left_spine<NodeT>(job, context);
|
||||
}
|
||||
}
|
||||
if (n->entryPresent && n->entry.rangeVersion > job->readVersion) {
|
||||
@@ -3570,16 +3627,16 @@ PRESERVE_NONE void left_side_iter(CheckJob *job, CheckContext *context) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(n);
|
||||
auto c = nextSibling(n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
}
|
||||
job->continuation = left_side_down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = leftSideDownLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
}
|
||||
if (commonLen == n->partialKeyLen) {
|
||||
@@ -3595,14 +3652,12 @@ PRESERVE_NONE void left_side_iter(CheckJob *job, CheckContext *context) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
if (job->maxV <= job->readVersion) {
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
}
|
||||
|
||||
++context->readContext.range_read_iterations_accum;
|
||||
@@ -3626,15 +3681,14 @@ PRESERVE_NONE void left_side_iter(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
}
|
||||
job->continuation = left_side_down_left_spine;
|
||||
job->continuation = leftSideDownLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3657,16 +3711,17 @@ PRESERVE_NONE void done_left_side_iter(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(job->n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3676,16 +3731,21 @@ PRESERVE_NONE void done_left_side_iter(CheckJob *job, CheckContext *context) {
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
template <class NodeT>
|
||||
void left_side_down_left_spine(CheckJob *job, CheckContext *context) {
|
||||
if (job->n->entryPresent) {
|
||||
if (job->n->entry.rangeVersion > job->readVersion) {
|
||||
assert(job->n->getType() == NodeT::kType);
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
|
||||
if (n->entryPresent) {
|
||||
if (n->entry.rangeVersion > job->readVersion) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = done_left_side_iter;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return done_left_side_iter(job, context);
|
||||
}
|
||||
job->n = getFirstChildExists(job->n);
|
||||
auto c = getFirstChildExists(n);
|
||||
job->n = c;
|
||||
job->continuation = leftSideDownLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
@@ -3706,8 +3766,7 @@ PRESERVE_NONE void right_side_iter(CheckJob *job, CheckContext *context) {
|
||||
if (i < commonLen) {
|
||||
auto c = n->partialKey()[i] <=> job->remaining[i];
|
||||
if (c > 0) {
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
} else {
|
||||
if ((n->parent != job->commonPrefixNode || i >= job->lcp) &&
|
||||
n->entryPresent && n->entry.rangeVersion > job->readVersion) {
|
||||
@@ -3719,13 +3778,15 @@ PRESERVE_NONE void right_side_iter(CheckJob *job, CheckContext *context) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
}
|
||||
if (commonLen == n->partialKeyLen) {
|
||||
@@ -3733,16 +3794,14 @@ PRESERVE_NONE void right_side_iter(CheckJob *job, CheckContext *context) {
|
||||
job->remaining =
|
||||
job->remaining.subspan(commonLen, job->remaining.size() - commonLen);
|
||||
} else if (n->partialKeyLen > int(job->remaining.size())) {
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
++context->readContext.range_read_iterations_accum;
|
||||
|
||||
if (job->remaining.size() == 0) {
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
MUSTTAIL return down_left_spine<NodeT>(job, context);
|
||||
}
|
||||
|
||||
if (n->entryPresent && n->entry.pointVersion > job->readVersion) {
|
||||
@@ -3767,16 +3826,19 @@ PRESERVE_NONE void right_side_iter(CheckJob *job, CheckContext *context) {
|
||||
auto c = getChildGeq(n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
auto c = nextSibling(job->n);
|
||||
job->n = c;
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
job->continuation = downLeftSpineTable[c.getType()];
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4289,17 +4351,17 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
// Kick off the sequence of tail calls that finally returns once all jobs
|
||||
// are done
|
||||
inProgress->continuation(inProgress, &context);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
Arena arena;
|
||||
auto *results2 = new (arena) Result[count];
|
||||
CheckContext context2;
|
||||
context2.readContext.impl = this;
|
||||
useSequential(reads, results2, count, context2);
|
||||
assert(memcmp(result, results2, count) == 0);
|
||||
assert(context.readContext == context2.readContext);
|
||||
Arena arena;
|
||||
auto *results2 = new (arena) Result[count];
|
||||
CheckContext context2;
|
||||
context2.readContext.impl = this;
|
||||
useSequential(reads, results2, count, context2);
|
||||
assert(memcmp(result, results2, count) == 0);
|
||||
assert(context.readContext == context2.readContext);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
useSequential(reads, result, count, context);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user