diff --git a/CMakeLists.txt b/CMakeLists.txt index 496b4c3..9463824 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,8 +21,12 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) "MinSizeRel" "RelWithDebInfo") endif() -add_compile_options(-fdata-sections -ffunction-sections - -Wno-return-stack-address) +add_compile_options(-fdata-sections -ffunction-sections) + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_options(-Wno-maybe-uninitialized) +endif() + if(APPLE) add_link_options(-Wl,-dead_strip) else() diff --git a/ConflictSet.cpp b/ConflictSet.cpp index ae008c7..ac6f159 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -515,6 +515,7 @@ struct FirstGeqStepwise { FirstGeqStepwise(Node *n, std::span 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 begin, const std::span 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 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 ""; + } + 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;