From 2037d37c6608863f49ccdb6cc003a2d07736f32d Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Wed, 4 Sep 2024 12:11:16 -0700 Subject: [PATCH] checkRangeLeftSide --- ConflictSet.cpp | 148 +++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 77 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 98b2b74..0d62e65 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -2510,104 +2510,99 @@ downLeftSpine: namespace { // Return true if the max version among all keys that start with key[:prefixLen] // that are >= key is <= readVersion -struct CheckRangeLeftSide { +bool checkRangeLeftSide(Node *n, std::span key, int prefixLen, + InternalVersionT readVersion, ReadContext *tls) { bool ok; + auto remaining = key; + int searchPathLen = 0; + for (;; ++tls->range_read_iterations_accum) { + if (remaining.size() == 0) { + assert(searchPathLen >= prefixLen); + ok = maxVersion(n) <= readVersion; + return ok; + } - bool step(Node *n, std::span key, int prefixLen, - InternalVersionT readVersion, ReadContext *tls) { - auto remaining = key; - int searchPathLen = 0; - for (;; ++tls->range_read_iterations_accum) { - if (remaining.size() == 0) { - assert(searchPathLen >= prefixLen); - ok = maxVersion(n) <= readVersion; - return true; + if (searchPathLen >= prefixLen) { + if (!checkMaxBetweenExclusive(n, remaining[0], 256, readVersion, tls)) { + ok = false; + return ok; } + } - if (searchPathLen >= prefixLen) { - if (!checkMaxBetweenExclusive(n, remaining[0], 256, readVersion, tls)) { - ok = false; - return true; + auto [child, maxV] = getChildAndMaxVersion(n, remaining[0]); + if (child == nullptr) { + auto c = getChildGeq(n, remaining[0]); + if (c != nullptr) { + if (searchPathLen < prefixLen) { + n = c; + goto downLeftSpine; } + n = c; + ok = maxVersion(n) <= readVersion; + return ok; + } else { + n = nextSibling(n); + if (n == nullptr) { + ok = true; + return ok; + } + goto downLeftSpine; } + } - auto [child, maxV] = getChildAndMaxVersion(n, remaining[0]); - if (child == nullptr) { - auto c = getChildGeq(n, remaining[0]); - if (c != nullptr) { + n = child; + remaining = remaining.subspan(1, remaining.size() - 1); + ++searchPathLen; + + if (n->partialKeyLen > 0) { + int commonLen = std::min(n->partialKeyLen, remaining.size()); + int i = longestCommonPrefix(n->partialKey(), remaining.data(), commonLen); + searchPathLen += i; + if (i < commonLen) { + auto c = n->partialKey()[i] <=> remaining[i]; + if (c > 0) { if (searchPathLen < prefixLen) { - n = c; goto downLeftSpine; } - n = c; + if (n->entryPresent && n->entry.rangeVersion > readVersion) { + ok = false; + return ok; + } ok = maxVersion(n) <= readVersion; - return true; + return ok; } else { n = nextSibling(n); if (n == nullptr) { ok = true; - return true; + return ok; } goto downLeftSpine; } } - - n = child; - remaining = remaining.subspan(1, remaining.size() - 1); - ++searchPathLen; - - if (n->partialKeyLen > 0) { - int commonLen = std::min(n->partialKeyLen, remaining.size()); - int i = - longestCommonPrefix(n->partialKey(), remaining.data(), commonLen); - searchPathLen += i; - if (i < commonLen) { - auto c = n->partialKey()[i] <=> remaining[i]; - if (c > 0) { - if (searchPathLen < prefixLen) { - goto downLeftSpine; - } - if (n->entryPresent && n->entry.rangeVersion > readVersion) { - ok = false; - return true; - } - ok = maxVersion(n) <= readVersion; - return true; - } else { - n = nextSibling(n); - if (n == nullptr) { - ok = true; - return true; - } - goto downLeftSpine; - } + if (commonLen == n->partialKeyLen) { + // partial key matches + remaining = remaining.subspan(commonLen, remaining.size() - commonLen); + } else if (n->partialKeyLen > int(remaining.size())) { + assert(searchPathLen >= prefixLen); + if (n->entryPresent && n->entry.rangeVersion > readVersion) { + ok = false; + return ok; } - if (commonLen == n->partialKeyLen) { - // partial key matches - remaining = - remaining.subspan(commonLen, remaining.size() - commonLen); - } else if (n->partialKeyLen > int(remaining.size())) { - assert(searchPathLen >= prefixLen); - if (n->entryPresent && n->entry.rangeVersion > readVersion) { - ok = false; - return true; - } - ok = maxVersion(n) <= readVersion; - return true; - } - } - if (maxV <= readVersion) { - ok = true; - return true; + ok = maxVersion(n) <= readVersion; + return ok; } } - downLeftSpine: - for (; !n->entryPresent; n = getFirstChildExists(n)) { + if (maxV <= readVersion) { + ok = true; + return ok; } - ok = n->entry.rangeVersion <= readVersion; - return true; } -}; +downLeftSpine: + for (; !n->entryPresent; n = getFirstChildExists(n)) { + } + ok = n->entry.rangeVersion <= readVersion; + return ok; +} // Return true if the max version among all keys that start with key[:prefixLen] // that are < key is <= readVersion @@ -2816,13 +2811,12 @@ bool checkRangeRead(Node *n, std::span begin, // This makes it safe to check maxVersion within CheckRangeLeftSide. If this // were false, then we would have returned above since lcp == begin.size(). assert(!(n->parent == nullptr && begin.size() == 0)); - CheckRangeLeftSide checkRangeLeftSide{}; - checkRangeLeftSide.step(n, begin, lcp + 1, readVersion, tls); + bool lhsOk = checkRangeLeftSide(n, begin, lcp + 1, readVersion, tls); CheckRangeRightSide checkRangeRightSide{n, end, lcp + 1, readVersion, tls}; for (; !checkRangeRightSide.step(); ++tls->range_read_iterations_accum) ; - return checkRangeLeftSide.ok && checkRangeRightSide.ok; + return lhsOk && checkRangeRightSide.ok; } #ifdef __x86_64__