From 0c8a0519131956c2173c9165b132c2303820d404 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Mon, 14 Oct 2024 17:16:56 -0700 Subject: [PATCH] Avoid more branches on type --- ConflictSet.cpp | 56 ++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 44c9cb6..348d671 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -2534,25 +2534,26 @@ Vector 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 -bool checkRangeStartsWith(NodeT *n, std::span key, int begin, - int end, InternalVersionT readVersion, +bool checkRangeStartsWith(NodeT *nTyped, std::span 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 PRESERVE_NONE void common_prefix_iter(CheckJob *, CheckContext *); +template PRESERVE_NONE void done_common_prefix_iter(CheckJob *, CheckContext *); static Continuation commonPrefixIterTable[] = { @@ -3287,6 +3289,11 @@ static Continuation commonPrefixIterTable[] = { common_prefix_iter, common_prefix_iter, common_prefix_iter}; +static Continuation doneCommonPrefixIterTable[] = { + done_common_prefix_iter, done_common_prefix_iter, + done_common_prefix_iter, done_common_prefix_iter, + done_common_prefix_iter}; + template 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; + 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; + 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 PRESERVE_NONE void done_common_prefix_iter(CheckJob *job, CheckContext *context) { + assert(NodeT::kType == job->n->getType()); + NodeT *n = static_cast(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;