Range write WIP

This commit is contained in:
2024-01-31 17:06:59 -08:00
parent 812eb27708
commit 96aca4a1da
2 changed files with 88 additions and 30 deletions

View File

@@ -6,6 +6,7 @@
#include <cassert>
#include <cstdint>
#include <cstring>
#include <inttypes.h>
#include <limits>
#include <span>
#include <string>
@@ -35,7 +36,7 @@ enum class Type : int8_t {
struct Node {
/* begin section that's copied to the next node */
Node *parent = nullptr;
int64_t maxVersion = std::numeric_limits<int64_t>::lowest();
int64_t maxVersion;
Entry entry;
int16_t numChildren = 0;
bool entryPresent = false;
@@ -85,6 +86,16 @@ struct BitSet {
}
}
void reset(int i) {
assert(0 <= i);
assert(i < 256);
if (i < 128) {
lo &= ~(__uint128_t(1) << i);
} else {
hi &= ~(__uint128_t(1) << (i - 128));
}
}
int firstSetGeq(int i) const {
if (i < 128) {
int a = std::countr_zero(lo >> i);
@@ -552,6 +563,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index) {
(self->numChildren - (nodeIndex + 1)));
} else if (self->type == Type::Node48) {
auto *self48 = static_cast<Node48 *>(self);
self48->bitSet.reset(index);
int8_t toRemoveChildrenIndex = std::exchange(self48->index[index], -1);
int8_t lastChildrenIndex = --self48->nextFree;
assert(toRemoveChildrenIndex >= 0);
@@ -564,6 +576,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index) {
}
} else {
auto *self256 = static_cast<Node256 *>(self);
self256->bitSet.reset(index);
self256->children[index] = nullptr;
}
--self->numChildren;
@@ -762,6 +775,7 @@ outerLoop:
auto &child = getOrCreateChild(self, key.front());
if (!child) {
child = newNode();
child->maxVersion = writeVersion;
child->parent = self;
child->parentsIndex = key.front();
}
@@ -816,18 +830,45 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
void addWrites(const WriteRange *writes, int count) {
for (int i = 0; i < count; ++i) {
const auto &w = writes[i];
// TODO support non-point writes
assert(w.end.len == 0);
auto *n = insert(&root, std::span<const uint8_t>(w.begin.p, w.begin.len),
w.writeVersion);
if (!n->entryPresent) {
auto *p = prevLogical(n);
assert(p != nullptr);
if (w.end.len > 0) {
auto *n = insert(&root, std::span<const uint8_t>(w.end.p, w.end.len),
std::numeric_limits<int64_t>::lowest());
if (!n->entryPresent) {
auto *p = prevLogical(n);
assert(p != nullptr);
n->entryPresent = true;
n->entry.pointVersion = p->entry.rangeVersion;
n->entry.rangeVersion = p->entry.rangeVersion;
n->maxVersion = p->entry.rangeVersion;
}
auto *end = n;
n = insert(&root, std::span<const uint8_t>(w.begin.p, w.begin.len),
w.writeVersion);
n->entryPresent = true;
n->entry.pointVersion = w.writeVersion;
n->entry.rangeVersion = p->entry.rangeVersion;
n->entry.rangeVersion = w.writeVersion;
for (n = nextLogical(n); n != end;) {
auto *old = n;
n = nextLogical(n);
if (old->numChildren == 0 && old->parent != nullptr) {
eraseChild(old->parent, old->parentsIndex);
}
}
} else {
n->entry.pointVersion = std::max(n->entry.pointVersion, w.writeVersion);
auto *n =
insert(&root, std::span<const uint8_t>(w.begin.p, w.begin.len),
w.writeVersion);
if (!n->entryPresent) {
auto *p = prevLogical(n);
assert(p != nullptr);
n->entryPresent = true;
n->entry.pointVersion = w.writeVersion;
n->entry.rangeVersion = p->entry.rangeVersion;
} else {
n->entry.pointVersion =
std::max(n->entry.pointVersion, w.writeVersion);
}
}
}
}
@@ -952,12 +993,14 @@ void printLogical(std::string &result, Node *node) {
assert(n != nullptr);
auto partialKey = printable(Key{n->partialKey, n->partialKeyLen});
if (n->entryPresent) {
fprintf(file, " k_%p [label=\"m=%d p=%d r=%d %s\"];\n", (void *)n,
int(n->maxVersion), int(n->entry.pointVersion),
int(n->entry.rangeVersion), partialKey.c_str());
fprintf(file,
" k_%p [label=\"m=%" PRId64 " p=%" PRId64 " r=%" PRId64
" %s\"];\n",
(void *)n, n->maxVersion, n->entry.pointVersion,
n->entry.rangeVersion, partialKey.c_str());
} else {
fprintf(file, " k_%p [label=\"m=%d %s\"];\n", (void *)n,
int(n->maxVersion), partialKey.c_str());
fprintf(file, " k_%p [label=\"m=%" PRId64 " %s\"];\n", (void *)n,
n->maxVersion, partialKey.c_str());
}
for (int child = getChildGeq(n, 0); child >= 0;
child = getChildGeq(n, child + 1)) {
@@ -1002,9 +1045,9 @@ void checkParentPointers(Node *node, bool &success) {
}
if (node->maxVersion != expected) {
Arena arena;
fprintf(stderr, "%s has max version %d. Expected %d\n",
printable(getSearchPath(arena, node)).c_str(),
int(node->maxVersion), int(expected));
fprintf(stderr, "%s has max version %" PRId64 " . Expected %" PRId64 "\n",
printable(getSearchPath(arena, node)).c_str(), node->maxVersion,
expected);
success = false;
}
return expected;