From 98dccf5c23f005541517a47768742a44609631b6 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Wed, 14 Feb 2024 17:01:00 -0800 Subject: [PATCH] WIP checkLeftOfPyramid seems to be correct --- CMakeLists.txt | 4 +- ConflictSet.cpp | 104 +++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6033ea..6513bd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ target_include_directories(${PROJECT_NAME}_object add_library(${PROJECT_NAME} SHARED $) if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) - set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) + # set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C) endif() if(NOT APPLE) @@ -71,7 +71,7 @@ endif() add_library(${PROJECT_NAME}_static STATIC $) if(NOT CMAKE_BUILD_TYPE STREQUAL Debug) - set_target_properties(${PROJECT_NAME}_static PROPERTIES LINKER_LANGUAGE C) + # set_target_properties(${PROJECT_NAME}_static PROPERTIES LINKER_LANGUAGE C) endif() if(NOT APPLE AND CMAKE_OBJCOPY) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 1ccfa7a..bfcedfa 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -736,14 +736,21 @@ int64_t maxRightOf(Node *n, int begin) { return result; } +// Return the maximum version among all keys starting with the search path of +// `n` + a child > `begin` int64_t maxRightOfExclusive(Node *n, int begin) { int64_t result = std::numeric_limits::lowest(); + int index = begin; for (;;) { - begin = getChildGeq(n, begin + 1); - if (begin < 0) { + index = getChildGeq(n, index + 1); + if (index < 0) { break; } - result = std::max(result, getChildExists(n, begin)->maxVersion); + auto *child = getChildExists(n, index); + if (index > begin + 1 && child->entryPresent) { + result = std::max(result, child->entry.rangeVersion); + } + result = std::max(result, child->maxVersion); } #if DEBUG_VERBOSE && !defined(NDEBUG) fprintf(stderr, "At `%s', max version right of %02x is %" PRId64 "\n", @@ -789,7 +796,8 @@ int64_t maxBetweenExclusive(Node *n, int begin, int end) { return result; } -// Returns true if the version of all keys >= key in n is <= readVersion +// Returns true if the version of all keys >= key in the subtree rooted at n is +// <= readVersion bool checkLeftOfPyramid(Node *n, const std::span key, int64_t readVersion) { auto remaining = key; @@ -799,30 +807,36 @@ bool checkLeftOfPyramid(Node *n, const std::span key, return true; } if (remaining.size() == 0) { - if (n->entryPresent) { - return n->entry.pointVersion <= readVersion; + return n->maxVersion <= readVersion; + } + + auto v = maxRightOfExclusive(n, remaining[0]); + if (v > readVersion) { + return false; + }; + { + int c = getChildGeq(n, int(remaining[0]) + 1); + if (c >= 0) { + auto *child = getChildExists(n, c); + if (child->entryPresent && child->entry.rangeVersion > readVersion) { + return false; + } } - int c = getChildGeq(n, 0); - assert(c >= 0); - n = getChildExists(n, c); - goto downLeftSpine; } int c = getChildGeq(n, remaining[0]); if (c == remaining[0]) { - auto v = maxRightOfExclusive(n, c); - if (v > readVersion) { - return false; - } n = getChildExists(n, c); remaining = remaining.subspan(1, remaining.size() - 1); } else { if (c >= 0) { n = getChildExists(n, c); - goto downLeftSpine; + if (n->entryPresent && n->entry.rangeVersion > readVersion) { + return false; + } + return n->maxVersion <= readVersion; } else { - n = nextSibling(n); - goto downLeftSpine; + return true; } } @@ -833,35 +847,26 @@ bool checkLeftOfPyramid(Node *n, const std::span key, if (c == 0) { continue; } - if (c > 0) { - goto downLeftSpine; + if (c < 0) { + return true; } else { - n = nextSibling(n); - goto downLeftSpine; + if (n->entryPresent && n->entry.rangeVersion > readVersion) { + return false; + } + return n->maxVersion <= readVersion; } } if (commonLen == n->partialKeyLen) { // partial key matches remaining = remaining.subspan(commonLen, remaining.size() - commonLen); } else if (n->partialKeyLen > int(remaining.size())) { - // n is the first physical node greater than remaining, and there's no - // eq node - goto downLeftSpine; + if (n->entryPresent && n->entry.rangeVersion > readVersion) { + return false; + } + return n->maxVersion <= readVersion; } } } -downLeftSpine: - if (n == nullptr) { - return true; - } - for (;;) { - if (n->entryPresent) { - return n->entry.rangeVersion <= readVersion; - } - int c = getChildGeq(n, 0); - assert(c >= 0); - n = getChildExists(n, c); - } } // Returns true if the version of all keys < key in n is <= readVersion @@ -1356,20 +1361,19 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { reads[i].readVersion)) ? Commit : Conflict; - // auto k = std::span(reads[i].begin.p, - // reads[i].begin.len); if (k.size() > 0) { - // bool expected = - // checkRangeRead(root, {}, k, reads[i].readVersion, arena); - // bool actual = checkRightOfPyramid(root, k, - // reads[i].readVersion); if (expected != actual) { - // #if DEBUG_VERBOSE && !defined(NDEBUG) - // fprintf(stderr, "Expected %d, got %d for [,%s)\n", - // int(expected), - // int(actual), printable(k).c_str()); - // #endif - // result[i] = TooOld; - // } - // } + auto k = std::span(reads[i].begin.p, reads[i].begin.len); + if (k.size() > 0) { + bool expected = checkRangeRead(root, k, std::vector(33, 0xff), + reads[i].readVersion, arena); + bool actual = checkLeftOfPyramid(root, k, reads[i].readVersion); + if (expected != actual) { +#if DEBUG_VERBOSE && !defined(NDEBUG) + fprintf(stderr, "Expected %d, got %d for [%s,)\n", int(expected), + int(actual), printable(k).c_str()); +#endif + result[i] = TooOld; + } + } } }