Share common prefix search in addWriteRange

This commit is contained in:
2024-02-16 17:50:21 -08:00
parent c20d0c5581
commit 69a1b9099d

View File

@@ -1396,46 +1396,87 @@ void destroyTree(Node *root) {
void addWriteRange(Node *&root, int64_t oldestVersion,
const ConflictSet::WriteRange &w) {
auto *begin = insert(&root, std::span<const uint8_t>(w.begin.p, w.begin.len),
w.writeVersion, true);
auto begin = std::span<const uint8_t>(w.begin.p, w.begin.len);
auto end = std::span<const uint8_t>(w.end.p, w.end.len);
const bool insertedBegin = !std::exchange(begin->entryPresent, true);
int lcp = longestCommonPrefix(begin.data(), end.data(),
std::min(begin.size(), end.size()));
auto remaining = begin.subspan(0, lcp);
auto *n = root;
for (;;) {
if (int(remaining.size()) < n->partialKeyLen + 1) {
break;
}
int i = 0;
for (; i < n->partialKeyLen; ++i) {
if (remaining[i] != n->partialKey[i]) {
break;
}
}
if (i != n->partialKeyLen) {
break;
}
int c = getChildGeq(n, remaining[n->partialKeyLen]);
if (c != remaining[n->partialKeyLen]) {
break;
}
n = getChildExists(n, c);
remaining = remaining.subspan(n->partialKeyLen + 1,
remaining.size() - (n->partialKeyLen + 1));
}
Node **useAsRoot = n->parent == nullptr
? &root
: &getChildExists(n->parent, n->parentsIndex);
int consumed = lcp - remaining.size();
consumed = 0;
useAsRoot = &root;
begin = begin.subspan(consumed, begin.size() - consumed);
end = end.subspan(consumed, end.size() - consumed);
auto *beginNode = insert(useAsRoot, begin, w.writeVersion, true);
const bool insertedBegin = !std::exchange(beginNode->entryPresent, true);
if (insertedBegin) {
auto *p = nextLogical(begin);
begin->entry.rangeVersion =
auto *p = nextLogical(beginNode);
beginNode->entry.rangeVersion =
p != nullptr ? p->entry.rangeVersion : oldestVersion;
begin->entry.pointVersion = w.writeVersion;
begin->maxVersion = w.writeVersion;
beginNode->entry.pointVersion = w.writeVersion;
beginNode->maxVersion = w.writeVersion;
}
begin->maxVersion = std::max(begin->maxVersion, w.writeVersion);
begin->entry.pointVersion =
std::max(begin->entry.pointVersion, w.writeVersion);
beginNode->maxVersion = std::max(beginNode->maxVersion, w.writeVersion);
beginNode->entry.pointVersion =
std::max(beginNode->entry.pointVersion, w.writeVersion);
auto *end = insert(&root, std::span<const uint8_t>(w.end.p, w.end.len),
w.writeVersion, false);
auto *endNode = insert(useAsRoot, end, w.writeVersion, false);
const bool insertedEnd = !std::exchange(end->entryPresent, true);
const bool insertedEnd = !std::exchange(endNode->entryPresent, true);
if (insertedEnd) {
auto *p = nextLogical(end);
end->entry.pointVersion =
auto *p = nextLogical(endNode);
endNode->entry.pointVersion =
p != nullptr ? p->entry.rangeVersion : oldestVersion;
end->maxVersion = std::max(end->maxVersion, end->entry.pointVersion);
endNode->maxVersion =
std::max(endNode->maxVersion, endNode->entry.pointVersion);
}
end->entry.rangeVersion = w.writeVersion;
endNode->entry.rangeVersion = w.writeVersion;
if (insertedEnd) {
// begin may have been invalidated
auto iter =
firstGeq(root, std::span<const uint8_t>(w.begin.p, w.begin.len));
assert(iter.cmp == 0);
begin = iter.n;
// beginNode may have been invalidated
beginNode = insert(useAsRoot, begin, w.writeVersion, true);
}
for (begin = nextLogical(begin); begin != end;) {
auto *old = begin;
begin = nextLogical(begin);
for (beginNode = nextLogical(beginNode); beginNode != endNode;) {
auto *old = beginNode;
beginNode = nextLogical(beginNode);
old->entryPresent = false;
if (old->numChildren == 0 && old->parent != nullptr) {
eraseChild(old->parent, old->parentsIndex);