From 0799aea3e8bf6c42d9e69ad7dfe3fca7d9d1fc6a Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Fri, 16 Feb 2024 18:35:28 -0800 Subject: [PATCH] Move newly test-only code --- Bench.cpp | 22 ++--- ConflictSet.cpp | 208 ++++++++++++++++++++++++------------------------ 2 files changed, 114 insertions(+), 116 deletions(-) diff --git a/Bench.cpp b/Bench.cpp index 57a4d45..280e5d0 100644 --- a/Bench.cpp +++ b/Bench.cpp @@ -606,19 +606,19 @@ constexpr int kOpsPerTx = 100; constexpr int kPrefixLen = 0; -std::span makeKey(Arena &arena, int index) { - - auto result = - std::span{new (arena) uint8_t[4 + kPrefixLen], 4 + kPrefixLen}; - index = __builtin_bswap32(index); - memset(result.data(), 0, kPrefixLen); - memcpy(result.data() + kPrefixLen, &index, 4); +std::span makeKey(Arena &arena, int64_t index) { // auto result = - // std::span{new (arena) uint8_t[32], 32}; - // for (int i = 0; i < 32; ++i) { - // result[i] = index & (1 << (31 - i)) ? '1' : '0'; - // } + // std::span{new (arena) uint8_t[4 + kPrefixLen], 4 + + // kPrefixLen}; + // index = __builtin_bswap32(index); + // memset(result.data(), 0, kPrefixLen); + // memcpy(result.data() + kPrefixLen, &index, 4); + + auto result = std::span{new (arena) uint8_t[64], 64}; + for (int i = 0; i < 64; ++i) { + result[i] = index & (1 << (64 - 1 - i)) ? '1' : '0'; + } return result; } diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 8b86573..73e9f14 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -551,115 +551,10 @@ struct SearchStepWise { } }; -struct FirstGeqStepwise { - Node *n; - std::span remaining; - int cmp; - - enum Phase { - Init, - // Being in this phase implies that the key matches the search path exactly - // up to this point - Search, - DownLeftSpine - }; - Phase phase; - - 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: - if (remaining.size() == 0) { - int c = getChildGeq(n, 0); - assert(c >= 0); - n = getChildExists(n, c); - return downLeftSpine(); - } else { - int c = getChildGeq(n, remaining[0]); - if (c == remaining[0]) { - n = getChildExists(n, c); - remaining = remaining.subspan(1, remaining.size() - 1); - } else { - if (c >= 0) { - n = getChildExists(n, c); - return downLeftSpine(); - } else { - n = nextSibling(n); - return downLeftSpine(); - } - } - } - if (n->partialKeyLen > 0) { - int commonLen = std::min(n->partialKeyLen, remaining.size()); - for (int i = 0; i < commonLen; ++i) { - auto c = n->partialKey[i] <=> remaining[i]; - if (c == 0) { - continue; - } - if (c > 0) { - return downLeftSpine(); - } else { - n = nextSibling(n); - return downLeftSpine(); - } - } - 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 - return downLeftSpine(); - } - } - [[fallthrough]]; - case Init: - phase = Search; - 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; - } - return false; - } - __builtin_unreachable(); // GCOVR_EXCL_LINE - } - - bool downLeftSpine() { - phase = DownLeftSpine; - if (n == nullptr || n->entryPresent) { - cmp = 1; - return true; - } - return step(); - } -}; - -Iterator firstGeq(Node *n, const std::span key) { - FirstGeqStepwise stepwise{n, key}; - while (!stepwise.step()) - ; - return {stepwise.n, stepwise.cmp}; -} - namespace { std::string getSearchPathPrintable(Node *n); } -// TODO rewrite in terms of FirstGeqStepwise? -// // Logically this is the same as performing firstGeq and then checking against // point or range version according to cmp, but this version short circuits as // soon as it can prove that there's no conflict. @@ -1733,6 +1628,109 @@ void checkParentPointers(Node *node, bool &success) { } } +struct FirstGeqStepwise { + Node *n; + std::span remaining; + int cmp; + + enum Phase { + Init, + // Being in this phase implies that the key matches the search path exactly + // up to this point + Search, + DownLeftSpine + }; + Phase phase; + + 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: + if (remaining.size() == 0) { + int c = getChildGeq(n, 0); + assert(c >= 0); + n = getChildExists(n, c); + return downLeftSpine(); + } else { + int c = getChildGeq(n, remaining[0]); + if (c == remaining[0]) { + n = getChildExists(n, c); + remaining = remaining.subspan(1, remaining.size() - 1); + } else { + if (c >= 0) { + n = getChildExists(n, c); + return downLeftSpine(); + } else { + n = nextSibling(n); + return downLeftSpine(); + } + } + } + if (n->partialKeyLen > 0) { + int commonLen = std::min(n->partialKeyLen, remaining.size()); + for (int i = 0; i < commonLen; ++i) { + auto c = n->partialKey[i] <=> remaining[i]; + if (c == 0) { + continue; + } + if (c > 0) { + return downLeftSpine(); + } else { + n = nextSibling(n); + return downLeftSpine(); + } + } + 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 + return downLeftSpine(); + } + } + [[fallthrough]]; + case Init: + phase = Search; + 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; + } + return false; + } + __builtin_unreachable(); // GCOVR_EXCL_LINE + } + + bool downLeftSpine() { + phase = DownLeftSpine; + if (n == nullptr || n->entryPresent) { + cmp = 1; + return true; + } + return step(); + } +}; + +Iterator firstGeq(Node *n, const std::span key) { + FirstGeqStepwise stepwise{n, key}; + while (!stepwise.step()) + ; + return {stepwise.n, stepwise.cmp}; +} + Iterator firstGeq(Node *n, std::string_view key) { return firstGeq( n, std::span((const uint8_t *)key.data(), key.size()));