From d89028dd2fec23441ab4710403454143f90a5a45 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Tue, 6 Aug 2024 14:45:52 -0700 Subject: [PATCH] Inline SearchStepWise into checkRangeRead This improves clang codegen --- ConflictSet.cpp | 69 +++++++++++++++++-------------------------------- 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 65bf405..e4ed8d9 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -1849,43 +1849,6 @@ int longestCommonPrefix(const uint8_t *ap, const uint8_t *bp, int cl) { return i; } -// Performs a physical search for remaining -struct SearchStepWise { - Node *n; - InternalVersionT maxV; - std::span remaining; - - SearchStepWise() {} - SearchStepWise(Node *n, std::span remaining) - : n(n), remaining(remaining) { - assert(n->partialKeyLen == 0); - } - - bool step() { - if (remaining.size() == 0) { - return true; - } - auto [child, v] = getChildAndMaxVersion(n, remaining[0]); - maxV = v; - if (child == nullptr) { - return true; - } - if (child->partialKeyLen > 0) { - int cl = std::min(child->partialKeyLen, remaining.size() - 1); - int i = - longestCommonPrefix(child->partialKey(), remaining.data() + 1, cl); - if (i != child->partialKeyLen) { - return true; - } - } - n = child; - remaining = - remaining.subspan(1 + child->partialKeyLen, - remaining.size() - (1 + child->partialKeyLen)); - return false; - } -}; - // Logically this is the same as performing firstGeq and then checking against // point or range version according to cmp, but this version short circuits as // soon as it can prove that there's no conflict. @@ -2820,30 +2783,44 @@ bool checkRangeRead(Node *n, std::span begin, ++tls->range_read_accum; - SearchStepWise search{n, begin.subspan(0, lcp)}; + auto remaining = begin.subspan(0, lcp); Arena arena; for (;; ++tls->range_read_iterations_accum) { - assert(getSearchPath(arena, search.n) <=> - begin.subspan(0, lcp - search.remaining.size()) == + assert(getSearchPath(arena, n) <=> + begin.subspan(0, lcp - remaining.size()) == 0); - if (search.step()) { + if (remaining.size() == 0) { break; } - if (search.maxV <= readVersion) { + auto [child, v] = getChildAndMaxVersion(n, remaining[0]); + if (child == nullptr) { + break; + } + if (child->partialKeyLen > 0) { + int cl = std::min(child->partialKeyLen, remaining.size() - 1); + int i = + longestCommonPrefix(child->partialKey(), remaining.data() + 1, cl); + if (i != child->partialKeyLen) { + break; + } + } + if (v <= readVersion) { ++tls->range_read_short_circuit_accum; return true; } + n = child; + remaining = + remaining.subspan(1 + child->partialKeyLen, + remaining.size() - (1 + child->partialKeyLen)); } - assert(getSearchPath(arena, search.n) <=> - begin.subspan(0, lcp - search.remaining.size()) == + assert(getSearchPath(arena, n) <=> begin.subspan(0, lcp - remaining.size()) == 0); - const int consumed = lcp - search.remaining.size(); + const int consumed = lcp - remaining.size(); assume(consumed >= 0); begin = begin.subspan(consumed, int(begin.size()) - consumed); end = end.subspan(consumed, int(end.size()) - consumed); - n = search.n; lcp -= consumed; if (lcp == int(begin.size())) {