Avoid more branches on type
This commit is contained in:
@@ -2534,25 +2534,26 @@ Vector<uint8_t> getSearchPath(Arena &arena, Node *n) {
|
||||
// Precondition: transitively, no child of n has a search path that's a longer
|
||||
// prefix of key than n
|
||||
template <class NodeT>
|
||||
bool checkRangeStartsWith(NodeT *n, std::span<const uint8_t> key, int begin,
|
||||
int end, InternalVersionT readVersion,
|
||||
bool checkRangeStartsWith(NodeT *nTyped, std::span<const uint8_t> key,
|
||||
int begin, int end, InternalVersionT readVersion,
|
||||
ReadContext *tls) {
|
||||
Node *n;
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "%s(%02x,%02x)*\n", printable(key).c_str(), begin, end);
|
||||
#endif
|
||||
auto remaining = key;
|
||||
if (remaining.size() == 0) {
|
||||
return checkMaxBetweenExclusive(n, begin, end, readVersion, tls);
|
||||
return checkMaxBetweenExclusive(nTyped, begin, end, readVersion, tls);
|
||||
}
|
||||
|
||||
Node *child = getChild(n, remaining[0]);
|
||||
Node *child = getChild(nTyped, remaining[0]);
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
auto c = getChildGeq(nTyped, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
n = c;
|
||||
goto downLeftSpine;
|
||||
} else {
|
||||
n = nextSibling(n);
|
||||
n = nextSibling(nTyped);
|
||||
if (n == nullptr) {
|
||||
return true;
|
||||
}
|
||||
@@ -3280,6 +3281,7 @@ PRESERVE_NONE void begin(CheckJob *, CheckContext *);
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void common_prefix_iter(CheckJob *, CheckContext *);
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void done_common_prefix_iter(CheckJob *, CheckContext *);
|
||||
|
||||
static Continuation commonPrefixIterTable[] = {
|
||||
@@ -3287,6 +3289,11 @@ static Continuation commonPrefixIterTable[] = {
|
||||
common_prefix_iter<Node16>, common_prefix_iter<Node48>,
|
||||
common_prefix_iter<Node256>};
|
||||
|
||||
static Continuation doneCommonPrefixIterTable[] = {
|
||||
done_common_prefix_iter<Node0>, done_common_prefix_iter<Node3>,
|
||||
done_common_prefix_iter<Node16>, done_common_prefix_iter<Node48>,
|
||||
done_common_prefix_iter<Node256>};
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void left_side_iter(CheckJob *, CheckContext *);
|
||||
|
||||
@@ -3326,7 +3333,7 @@ PRESERVE_NONE void begin(CheckJob *job, CheckContext *context) {
|
||||
job->remaining = job->begin.subspan(0, job->lcp);
|
||||
|
||||
if (job->remaining.size() == 0) {
|
||||
job->continuation = done_common_prefix_iter;
|
||||
job->continuation = doneCommonPrefixIterTable[job->n->getType()];
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
}
|
||||
|
||||
@@ -3334,7 +3341,7 @@ PRESERVE_NONE void begin(CheckJob *job, CheckContext *context) {
|
||||
job->maxV = maxV;
|
||||
job->child = c;
|
||||
if (job->child == nullptr) {
|
||||
job->continuation = done_common_prefix_iter;
|
||||
job->continuation = doneCommonPrefixIterTable[job->n->getType()];
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
}
|
||||
|
||||
@@ -3355,7 +3362,8 @@ void common_prefix_iter(CheckJob *job, CheckContext *context) {
|
||||
int i =
|
||||
longestCommonPrefix(child->partialKey(), job->remaining.data() + 1, cl);
|
||||
if (i != child->partialKeyLen) {
|
||||
MUSTTAIL return done_common_prefix_iter(job, context);
|
||||
job->continuation = doneCommonPrefixIterTable[job->n->getType()];
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
}
|
||||
}
|
||||
job->n = child;
|
||||
@@ -3372,14 +3380,16 @@ void common_prefix_iter(CheckJob *job, CheckContext *context) {
|
||||
}
|
||||
|
||||
if (job->remaining.size() == 0) {
|
||||
MUSTTAIL return done_common_prefix_iter(job, context);
|
||||
job->continuation = done_common_prefix_iter<NodeT>;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
}
|
||||
|
||||
auto [c, maxV] = getChildAndMaxVersion(child, job->remaining[0]);
|
||||
job->maxV = maxV;
|
||||
job->child = c;
|
||||
if (job->child == nullptr) {
|
||||
MUSTTAIL return done_common_prefix_iter(job, context);
|
||||
job->continuation = done_common_prefix_iter<NodeT>;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
}
|
||||
|
||||
job->continuation = commonPrefixIterTable[c.getType()];
|
||||
@@ -3387,12 +3397,15 @@ void common_prefix_iter(CheckJob *job, CheckContext *context) {
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
template <class NodeT>
|
||||
PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
CheckContext *context) {
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
|
||||
{
|
||||
Arena arena;
|
||||
assert(getSearchPath(arena, job->n) <=>
|
||||
assert(getSearchPath(arena, n) <=>
|
||||
job->begin.subspan(0, job->lcp - job->remaining.size()) ==
|
||||
0);
|
||||
}
|
||||
@@ -3403,19 +3416,18 @@ PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
job->begin = job->begin.subspan(consumed, int(job->begin.size()) - consumed);
|
||||
job->end = job->end.subspan(consumed, int(job->end.size()) - consumed);
|
||||
job->lcp -= consumed;
|
||||
job->commonPrefixNode = job->n;
|
||||
job->commonPrefixNode = n;
|
||||
|
||||
if (job->lcp == int(job->begin.size())) {
|
||||
job->remaining = job->end;
|
||||
if (job->lcp == 0) {
|
||||
if (job->n->entryPresent &&
|
||||
job->n->entry.pointVersion > job->readVersion) {
|
||||
if (n->entryPresent && n->entry.pointVersion > job->readVersion) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
|
||||
if (!checkMaxBetweenExclusive(job->n, -1, job->remaining[0],
|
||||
job->readVersion, context->tls)) {
|
||||
if (!checkMaxBetweenExclusive(n, -1, job->remaining[0], job->readVersion,
|
||||
context->tls)) {
|
||||
job->setResult(false);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
@@ -3424,10 +3436,10 @@ PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
// This is a hack
|
||||
--job->lcp;
|
||||
|
||||
auto c = getChild(job->n, job->remaining[0]);
|
||||
auto c = getChild(n, job->remaining[0]);
|
||||
Node *child = c;
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(job->n, job->remaining[0]);
|
||||
auto c = getChildGeq(n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
@@ -3452,7 +3464,7 @@ PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
// If this were not true we would have returned above
|
||||
assert(job->begin.size() > 0);
|
||||
|
||||
if (!checkRangeStartsWith(job->n, job->begin.subspan(0, job->lcp),
|
||||
if (!checkRangeStartsWith(n, job->begin.subspan(0, job->lcp),
|
||||
job->begin[job->lcp], job->end[job->lcp],
|
||||
job->readVersion, context->tls)) {
|
||||
job->setResult(false);
|
||||
@@ -3461,11 +3473,11 @@ PRESERVE_NONE void done_common_prefix_iter(CheckJob *job,
|
||||
|
||||
job->remaining = job->begin;
|
||||
|
||||
auto [c, maxV] = getChildAndMaxVersion(job->n, job->remaining[0]);
|
||||
auto [c, maxV] = getChildAndMaxVersion(n, job->remaining[0]);
|
||||
job->maxV = maxV;
|
||||
Node *child = c;
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(job->n, job->remaining[0]);
|
||||
auto c = getChildGeq(n, job->remaining[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = left_side_down_left_spine;
|
||||
|
Reference in New Issue
Block a user