diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 51b24a1..35ba0db 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -547,6 +547,46 @@ Node *nextSibling(Node *node, Vector &searchPath) { } } +// Performs a physical search for remaining +struct SearchStepWise { + Node *n; + 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; + } else { + int c = getChildGeq(n, remaining[0]); + if (c == remaining[0]) { + auto *child = getChildExists(n, c); + int i = 0; + for (; i < child->partialKeyLen; ++i) { + if (!(i + 1 < int(remaining.size()) && + remaining[i + 1] == child->partialKey[i])) { + break; + } + } + if (i != child->partialKeyLen) { + return true; + } + n = child; + remaining = + remaining.subspan(1 + child->partialKeyLen, + remaining.size() - (1 + child->partialKeyLen)); + } else { + return true; + } + } + return false; + } +}; + struct FirstGeqStepwise { Node *n; std::span remaining; @@ -894,6 +934,26 @@ bytes: bool checkRangeRead(Node *n, const std::span begin, const std::span end, int64_t readVersion, Arena &arena) { + + int cl = std::min(begin.size(), end.size()); + int lcp = longestCommonPrefix(begin.data(), end.data(), cl); + + SearchStepWise search{n, begin.subspan(0, lcp)}; + for (;;) { + assert(getSearchPath(arena, search.n) <=> + begin.subspan(0, lcp - search.remaining.size()) == + 0); + if (search.n->maxVersion <= readVersion) { + return true; + } + if (search.step()) { + break; + } + } + assert(getSearchPath(arena, search.n) <=> + begin.subspan(0, lcp - search.remaining.size()) == + 0); + auto left = firstGeq(n, begin); #if DEBUG_VERBOSE && !defined(NDEBUG)