Convert checkPrefixRead to IteratorBase

This commit is contained in:
2024-11-22 15:37:53 -08:00
parent 7b14c8f9d5
commit 0619b6325c

View File

@@ -2037,6 +2037,8 @@ IteratorBase IteratorBase::getChildGeq(int index) {
} }
} }
InternalVersionT IteratorBase::getMaxVersion() { return ::maxVersion(node); }
bool IteratorBase::checkRangeVersionOfFirstGeq(InternalVersionT readVersion) { bool IteratorBase::checkRangeVersionOfFirstGeq(InternalVersionT readVersion) {
return ::checkRangeVersionOfFirstGeq(node, readVersion); return ::checkRangeVersionOfFirstGeq(node, readVersion);
} }
@@ -4616,7 +4618,7 @@ bool checkPointRead(IteratorBase n, const TrivialSpan key,
// Logically this is the same as performing firstGeq and then checking against // Logically this is the same as performing firstGeq and then checking against
// max version or range version if this prefix doesn't exist, but this version // max version or range version if this prefix doesn't exist, but this version
// short circuits as soon as it can prove that there's no conflict. // short circuits as soon as it can prove that there's no conflict.
bool checkPrefixRead(Node *n, const TrivialSpan key, bool checkPrefixRead(IteratorBase n, const TrivialSpan key,
InternalVersionT readVersion, ReadContext *readContext) { InternalVersionT readVersion, ReadContext *readContext) {
++readContext->prefix_read_accum; ++readContext->prefix_read_accum;
#if DEBUG_VERBOSE && !defined(NDEBUG) #if DEBUG_VERBOSE && !defined(NDEBUG)
@@ -4626,54 +4628,55 @@ bool checkPrefixRead(Node *n, const TrivialSpan key,
for (;; ++readContext->prefix_read_iterations_accum) { for (;; ++readContext->prefix_read_iterations_accum) {
if (remaining.size() == 0) { if (remaining.size() == 0) {
// There's no way to encode a prefix read of "", so n is not the root // There's no way to encode a prefix read of "", so n is not the root
return maxVersion(n) <= readVersion; return n.getMaxVersion() <= readVersion;
} }
auto [c, maxV] = getChildAndMaxVersion(n, remaining[0]); auto [c, maxV] = n.getChildAndMaxVersion(remaining[0]);
Node *child = c; IteratorBase child = c;
if (child == nullptr) { if (!child.valid()) {
auto c = getChildGeq(n, remaining[0]); auto c = n.getChildGeq(remaining[0]);
if (c != nullptr) { if (c.valid()) {
n = c; return c.checkRangeVersionOfFirstGeq(readVersion);
return checkRangeVersionOfFirstGeq(n, readVersion);
} else { } else {
n = nextSibling(n); n = n.nextSibling();
if (n == nullptr) { if (!n.valid()) {
return true; return true;
} }
return checkRangeVersionOfFirstGeq(n, readVersion); return n.checkRangeVersionOfFirstGeq(readVersion);
} }
} }
n = child; n = child;
remaining = remaining.subspan(1, remaining.size() - 1); remaining = remaining.subspan(1, remaining.size() - 1);
if (n->partialKeyLen > 0) { auto partialKey = n.partialKey();
int commonLen = std::min<int>(n->partialKeyLen, remaining.size()); if (partialKey.size() > 0) {
int i = longestCommonPrefix(n->partialKey(), remaining.data(), commonLen); int commonLen = std::min<int>(partialKey.size(), remaining.size());
int i =
longestCommonPrefix(partialKey.data(), remaining.data(), commonLen);
if (i < commonLen) { if (i < commonLen) {
auto c = n->partialKey()[i] <=> remaining[i]; auto c = partialKey[i] <=> remaining[i];
if (c > 0) { if (c > 0) {
return checkRangeVersionOfFirstGeq(n, readVersion); return n.checkRangeVersionOfFirstGeq(readVersion);
} else { } else {
n = nextSibling(n); n = n.nextSibling();
if (n == nullptr) { if (!n.valid()) {
return true; return true;
} }
return checkRangeVersionOfFirstGeq(n, readVersion); return n.checkRangeVersionOfFirstGeq(readVersion);
} }
} }
if (commonLen == n->partialKeyLen) { if (commonLen == partialKey.size()) {
// partial key matches // partial key matches
remaining = remaining.subspan(commonLen, remaining.size() - commonLen); remaining = remaining.subspan(commonLen, remaining.size() - commonLen);
} else if (n->partialKeyLen > remaining.size()) { } else if (partialKey.size() > remaining.size()) {
// n is the first physical node greater than remaining, and there's no // n is the first physical node greater than remaining, and there's no
// eq node. All physical nodes that start with prefix are reachable from // eq node. All physical nodes that start with prefix are reachable from
// n. // n.
if (maxV > readVersion) { if (maxV > readVersion) {
return false; return false;
} }
return checkRangeVersionOfFirstGeq(n, readVersion); return n.checkRangeVersionOfFirstGeq(readVersion);
} }
} }
@@ -4866,7 +4869,7 @@ bool checkRangeRead(Node *n, TrivialSpan begin, TrivialSpan end,
} }
if (lcp == begin.size() - 1 && end.size() == begin.size() && if (lcp == begin.size() - 1 && end.size() == begin.size() &&
begin.back() + 1 == end.back()) { begin.back() + 1 == end.back()) {
return checkPrefixRead(n, begin, readVersion, readContext); return checkPrefixRead(IteratorBase{n}, begin, readVersion, readContext);
} }
++readContext->range_read_accum; ++readContext->range_read_accum;