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

@@ -21,8 +21,12 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"MinSizeRel" "RelWithDebInfo") "MinSizeRel" "RelWithDebInfo")
endif() endif()
add_compile_options(-fdata-sections -ffunction-sections add_compile_options(-fdata-sections -ffunction-sections)
-Wno-return-stack-address)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wno-maybe-uninitialized)
endif()
if(APPLE) if(APPLE)
add_link_options(-Wl,-dead_strip) add_link_options(-Wl,-dead_strip)
else() else()

View File

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