diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 84df967..5305ed0 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -997,40 +997,6 @@ void eraseChild(Node *self, uint8_t index) { } } -void debugPrintDot(FILE *file, Node *node) { - - struct DebugDotPrinter { - - explicit DebugDotPrinter(FILE *file) : file(file) {} - - void print(Node *n) { - assert(n != nullptr); - if (n->entryPresent) { - fprintf(file, " k_%p [label=\"m=%d p=%d r=%d\"];\n", (void *)n, - int(n->maxVersion), int(n->entry.pointVersion), - int(n->entry.rangeVersion)); - } else { - fprintf(file, " k_%p [label=\"m=%d\"];\n", (void *)n, - int(n->maxVersion)); - } - for (int child = getChildGeq(n, 0); child >= 0; - child = getChildGeq(n, child + 1)) { - auto *c = getChildExists(n, child); - fprintf(file, " k_%p -> k_%p [label=\"'%02x'\"];\n", (void *)n, - (void *)c, child); - print(c); - } - } - FILE *file; - }; - - fprintf(file, "digraph ConflictSet {\n"); - assert(node != nullptr); - DebugDotPrinter printer{file}; - printer.print(node); - fprintf(file, "}\n"); -} - Node *nextPhysical(Node *node) { int index = -1; for (;;) { @@ -1129,6 +1095,8 @@ struct Iterator { int cmp; }; +std::string_view getSearchPath(Arena &arena, Node *n); + Iterator lastLeq(Node *n, const std::span key) { auto remaining = key; for (;;) { @@ -1196,6 +1164,9 @@ void insert(Node **self_, std::span key, int64_t writeVersion) { } } +std::string printable(std::string_view key); +std::string printable(const Key &key); + struct __attribute__((visibility("hidden"))) ConflictSet::Impl { void check(const ReadRange *reads, Result *result, int count) const { for (int i = 0; i < count; ++i) { @@ -1330,6 +1301,91 @@ __attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) { // GCOVR_EXCL_START +std::string printable(std::string_view key) { + std::string result; + for (uint8_t c : key) { + result += "x"; + result += "0123456789abcdef"[c / 16]; + result += "0123456789abcdef"[c % 16]; + } + return result; +} + +std::string printable(const Key &key) { + return printable(std::string_view((const char *)key.p, key.len)); +} + +std::string_view getSearchPath(Arena &arena, Node *n) { + if (n->parent == nullptr) { + return {}; + } + auto result = vector(arena); + for (; n->parent != nullptr; n = n->parent) { + result.push_back(n->parentsIndex); + } + std::reverse(result.begin(), result.end()); + return std::string_view((const char *)&result[0], result.size()); // NOLINT +} + +void printLogical(std::string &result, Node *node) { + Arena arena; + for (Node *iter = node; iter != nullptr;) { + auto *next = nextLogical(iter); + std::string key; + for (uint8_t c : getSearchPath(arena, iter)) { + key += "x"; + key += "0123456789abcdef"[c / 16]; + key += "0123456789abcdef"[c % 16]; + } + if (iter->entry.pointVersion == iter->entry.rangeVersion) { + result += key + " -> " + std::to_string(iter->entry.pointVersion) + "\n"; + } else { + result += key + " -> " + std::to_string(iter->entry.pointVersion) + "\n"; + if (next == nullptr || (getSearchPath(arena, next) != + (std::string(getSearchPath(arena, iter)) + + std::string("\x00", 1)))) { + result += + key + "x00 -> " + std::to_string(iter->entry.rangeVersion) + "\n"; + } + } + iter = next; + } +} + +void debugPrintDot(FILE *file, Node *node) { + + struct DebugDotPrinter { + + explicit DebugDotPrinter(FILE *file) : file(file) {} + + void print(Node *n) { + assert(n != nullptr); + if (n->entryPresent) { + fprintf(file, " k_%p [label=\"m=%d p=%d r=%d\"];\n", (void *)n, + int(n->maxVersion), int(n->entry.pointVersion), + int(n->entry.rangeVersion)); + } else { + fprintf(file, " k_%p [label=\"m=%d\"];\n", (void *)n, + int(n->maxVersion)); + } + for (int child = getChildGeq(n, 0); child >= 0; + child = getChildGeq(n, child + 1)) { + auto *c = getChildExists(n, child); + fprintf(file, " k_%p -> k_%p [label=\"'%02x'\"];\n", (void *)n, + (void *)c, child); + print(c); + } + } + FILE *file; + }; + + fprintf(file, "digraph ConflictSet {\n"); + assert(node != nullptr); + DebugDotPrinter printer{file}; + printer.print(node); + fprintf(file, "}\n"); +} + void checkParentPointers(Node *node, bool &success) { for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) { auto *child = getChildExists(node, i); @@ -1383,9 +1439,7 @@ bool checkCorrectness(Node *node, ReferenceImpl &refImpl) { return success; } namespace std { -void __throw_length_error(const char *) { - __builtin_unreachable(); -} +void __throw_length_error(const char *) { __builtin_unreachable(); } } // namespace std #ifdef ENABLE_MAIN