From 403608c79457f0e2611326f1ccca638db80951a9 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Fri, 9 Feb 2024 12:45:34 -0800 Subject: [PATCH] WIP just need to identify nodes on begin -> end path --- ConflictSet.cpp | 104 ++++++++++++++++++++++++++++++++---------------- Internal.h | 7 ++++ 2 files changed, 76 insertions(+), 35 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 70f61db..61c7a24 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -485,6 +485,21 @@ Node *nextPhysical(Node *node) { } } +Node *nextPhysicalSkipSubtree(Node *node) { + int index = -1; + for (;;) { + index = node->parentsIndex; + node = node->parent; + if (node == nullptr) { + return nullptr; + } + auto nextChild = getChildGeq(node, index + 1); + if (nextChild >= 0) { + return getChildExists(node, nextChild); + } + } +} + Node *nextLogical(Node *node) { for (node = nextPhysical(node); node != nullptr && !node->entryPresent; node = nextPhysical(node)) @@ -711,33 +726,6 @@ bool checkRangeRead(Node *n, const std::span begin, } } - 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; - } - } - } - - // TODO make it sublinear if (!leftDone) { while (!left.step()) ; @@ -746,6 +734,43 @@ bool checkRangeRead(Node *n, const std::span begin, while (!right.step()) ; } + + Arena arena; + auto leftPath = vector(arena); + auto rightPath = vector(arena); + for (auto *iter = left.n; iter != nullptr; iter = iter->parent) { + leftPath.push_back(iter); + } + for (auto *iter = right.n; iter != nullptr; iter = iter->parent) { + rightPath.push_back(iter); + } + std::reverse(leftPath.begin(), leftPath.end()); + std::reverse(rightPath.begin(), rightPath.end()); + Node *lca = n; + int longestCommonPrefixSize = 0; + for (int i = 0, end = std::min(leftPath.size(), rightPath.size()); + i < end; ++i, ++longestCommonPrefixSize) { + if (leftPath[i] != rightPath[i]) { + break; + } + lca = leftPath[i]; + } + auto border = vector(arena); + for (int i = longestCommonPrefixSize; i < int(leftPath.size()); ++i) { + border.push_back(leftPath[i]); + } + for (int i = longestCommonPrefixSize; i < int(rightPath.size()); ++i) { + border.push_back(rightPath[i]); + } + +#if DEBUG_VERBOSE && !defined(NDEBUG) + fprintf(stderr, "firstGeq for `%s' got `%s'\n", printable(begin).c_str(), + getSearchPath(left.n).c_str()); + fprintf(stderr, "firstGeq for `%s' got `%s'\n", printable(end).c_str(), + getSearchPath(right.n).c_str()); + fprintf(stderr, "lca `%s'\n", getSearchPath(lca).c_str()); +#endif + if (left.n != nullptr && left.cmp != 0 && left.n->entry.rangeVersion > readVersion) { return false; @@ -754,16 +779,25 @@ bool checkRangeRead(Node *n, const std::span begin, return true; } assert(left.n != nullptr); - auto boundaryVersion = left.n->entry.pointVersion; - // Already checked left rangeVersion - if (boundaryVersion > readVersion) { + if (left.n->entry.pointVersion > readVersion) { return false; } - for (auto *iter = nextLogical(left.n); iter != right.n; - iter = nextLogical(iter)) { - if (std::max(iter->entry.pointVersion, iter->entry.rangeVersion) > - readVersion) { - return false; + + // TODO make it sublinear + for (auto *iter = nextPhysical(left.n); iter != right.n;) { + assert(iter != lca); + if (std::find(border.begin(), border.end(), iter) == border.end()) { + if (iter->maxVersion > readVersion) { + return false; + } + iter = nextPhysicalSkipSubtree(iter); + } else { + if (iter->entryPresent && + std::max(iter->entry.pointVersion, iter->entry.rangeVersion) > + readVersion) { + return false; + } + iter = nextPhysical(iter); } } return true; diff --git a/Internal.h b/Internal.h index a618dee..cd8a457 100644 --- a/Internal.h +++ b/Internal.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -183,6 +184,12 @@ template using Set = std::set, ArenaAlloc>; template auto set(Arena &arena) { return Set(ArenaAlloc(&arena)); } +template +using HashSet = + std::unordered_set, std::equal_to, ArenaAlloc>; +template auto hashSet(Arena &arena) { + return HashSet(ArenaAlloc(&arena)); +} template bool operator==(const ArenaAlloc &lhs, const ArenaAlloc &rhs) {