Check indices between left and right after they diverge

This commit is contained in:
2024-02-08 14:50:53 -08:00
parent b018ccc3ae
commit 2bd1bf93a9
2 changed files with 74 additions and 29 deletions

View File

@@ -515,6 +515,7 @@ struct FirstGeqStepwise {
FirstGeqStepwise(Node *n, std::span<const uint8_t> remaining)
: n(n), remaining(remaining), phase(Init) {}
// Not being done implies that n is not the firstGeq
bool step() {
switch (phase) {
case Search:
@@ -573,26 +574,30 @@ struct FirstGeqStepwise {
return downLeftSpine();
}
}
if (remaining.size() == 0 && n->entryPresent) {
cmp = 0;
return true;
}
return false;
case DownLeftSpine:
int c = getChildGeq(n, 0);
assert(c >= 0);
n = getChildExists(n, c);
if (n->entryPresent) {
cmp = 1;
return true;
}
int c = getChildGeq(n, 0);
assert(c >= 0);
n = getChildExists(n, c);
return false;
}
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
bool downLeftSpine() {
if (n == nullptr) {
phase = DownLeftSpine;
if (n == nullptr || n->entryPresent) {
cmp = 1;
return true;
}
phase = DownLeftSpine;
return step();
}
};
@@ -682,27 +687,57 @@ downLeftSpine:
}
}
namespace {
std::string getSearchPathPrintable(Node *n);
}
bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
const std::span<const uint8_t> end, int64_t readVersion) {
auto left = FirstGeqStepwise{n, begin};
auto right = FirstGeqStepwise{n, end};
bool leftDone = left.step();
bool rightDone = right.step();
assert(!leftDone);
assert(!rightDone);
for (;;) {
if (left.phase == FirstGeqStepwise::Search &&
right.phase == FirstGeqStepwise::Search &&
left.n->maxVersion <= readVersion) {
return true;
if (!leftDone && !rightDone) {
for (;;) {
if (left.phase == FirstGeqStepwise::Search &&
right.phase == FirstGeqStepwise::Search &&
left.n->maxVersion <= readVersion) {
return true;
}
leftDone = left.step();
rightDone = right.step();
if (leftDone || rightDone) {
break;
}
if (left.n != right.n) {
break;
}
}
leftDone = left.step();
rightDone = right.step();
if (leftDone || rightDone) {
break;
}
if (left.n != right.n) {
break;
}
if (!leftDone && !rightDone && left.n->parent == right.n->parent) {
// Check between left parent index and right parent index
int c = getChildGeq(left.n->parent, int(left.n->parentsIndex) + 1);
assert(c >= 0);
for (;;) {
if (c < right.n->parentsIndex) {
#if DEBUG_VERBOSE && !defined(NDEBUG)
fprintf(
stderr, "Check [%s, %s)\n",
getSearchPathPrintable(getChildExists(left.n->parent, c)).c_str(),
getSearchPathPrintable(
getChildExists(left.n->parent,
getChildGeq(left.n->parent, c + 1)))
.c_str());
#endif
if (getChildExists(left.n->parent, c)->maxVersion > readVersion) {
return false;
}
c = getChildGeq(left.n->parent, c + 1);
} else {
break;
}
}
}
@@ -715,11 +750,6 @@ bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
while (!right.step())
;
}
#if DEBUG_VERBOSE && !defined(NDEBUG)
fprintf(stderr, "Left firstGeq: %s, right firstGeq: %s\n",
getSearchPathPrintable(left.n).c_str(),
getSearchPathPrintable(right.n).c_str());
#endif
if (left.n != nullptr && left.cmp != 0 &&
left.n->entry.rangeVersion > readVersion) {
return false;
@@ -1032,6 +1062,17 @@ std::string getSearchPathPrintable(Node *n) {
}
}
std::string getPartialKeyPrintable(Node *n) {
Arena arena;
if (n == nullptr) {
return "<end>";
}
auto result = std::string((const char *)&n->parentsIndex,
n->parent == nullptr ? 0 : 1) +
std::string((const char *)n->partialKey, n->partialKeyLen);
return printable(result); // NOLINT
}
std::string strinc(std::string_view str, bool &ok) {
int index;
for (index = str.size() - 1; index >= 0; index--)
@@ -1071,7 +1112,7 @@ std::string getSearchPath(Node *n) {
[[maybe_unused]] void debugPrintDot(FILE *file, Node *node) {
constexpr int kSeparation = 2;
constexpr int kSeparation = 3;
struct DebugDotPrinter {
@@ -1084,10 +1125,10 @@ std::string getSearchPath(Node *n) {
" k_%p [label=\"m=%" PRId64 " p=%" PRId64 " r=%" PRId64
"\n%s\", pos=\"%d,%d!\"];\n",
(void *)n, n->maxVersion, n->entry.pointVersion,
n->entry.rangeVersion, getSearchPathPrintable(n).c_str(), x, y);
n->entry.rangeVersion, getPartialKeyPrintable(n).c_str(), x, y);
} else {
fprintf(file, " k_%p [label=\"m=%" PRId64 "\n%s\", pos=\"%d,%d!\"];\n",
(void *)n, n->maxVersion, getSearchPathPrintable(n).c_str(), x,
(void *)n, n->maxVersion, getPartialKeyPrintable(n).c_str(), x,
y);
}
x += kSeparation;