Compare commits
4 Commits
5ed9003a83
...
182c065c8e
| Author | SHA1 | Date | |
|---|---|---|---|
| 182c065c8e | |||
| 2dba0d5be3 | |||
| a1dfdf355c | |||
| 15919cb1c4 |
+25
-46
@@ -2922,25 +2922,22 @@ void consumePartialKey(Node *&self, std::span<const uint8_t> &key,
|
||||
key = key.subspan(partialKeyIndex, key.size() - partialKeyIndex);
|
||||
}
|
||||
|
||||
// Returns a pointer to the newly inserted node. Caller must set
|
||||
// `entryPresent`, and `entry` fields. All nodes along the search path of the
|
||||
// result will have `maxVersion` set to `writeVersion` as a postcondition. Nodes
|
||||
// along the search path may be invalidated.
|
||||
// Returns a pointer the pointer to the newly inserted node in the tree. Caller
|
||||
// must set `entryPresent`, and `entry` fields. All nodes along the search path
|
||||
// of the result will have `maxVersion` set to `writeVersion` as a
|
||||
// postcondition. Nodes along the search path may be invalidated.
|
||||
[[nodiscard]]
|
||||
Node *insert(Node **self, std::span<const uint8_t> key,
|
||||
InternalVersionT writeVersion, WriteContext *tls,
|
||||
ConflictSet::Impl *impl) {
|
||||
Node **insert(Node **self, std::span<const uint8_t> key,
|
||||
InternalVersionT writeVersion, WriteContext *tls,
|
||||
ConflictSet::Impl *impl) {
|
||||
|
||||
if ((*self)->partialKeyLen > 0) {
|
||||
consumePartialKey(*self, key, writeVersion, tls);
|
||||
}
|
||||
assert(maxVersion(*self, impl) <= writeVersion);
|
||||
setMaxVersion(*self, impl, writeVersion);
|
||||
|
||||
for (;; ++tls->accum.insert_iterations) {
|
||||
|
||||
if (key.size() == 0) {
|
||||
return *self;
|
||||
return self;
|
||||
}
|
||||
|
||||
auto &child = getOrCreateChild(*self, key.front(), writeVersion, tls);
|
||||
@@ -2953,7 +2950,7 @@ Node *insert(Node **self, std::span<const uint8_t> key,
|
||||
child->parentsIndex = key.front();
|
||||
setMaxVersion(child, impl, writeVersion);
|
||||
memcpy(child->partialKey(), key.data() + 1, child->partialKeyLen);
|
||||
return child;
|
||||
return &child;
|
||||
}
|
||||
|
||||
self = &child;
|
||||
@@ -2996,7 +2993,7 @@ void addPointWrite(Node *&root, std::span<const uint8_t> key,
|
||||
InternalVersionT writeVersion, WriteContext *tls,
|
||||
ConflictSet::Impl *impl) {
|
||||
++tls->accum.point_writes;
|
||||
auto *n = insert(&root, key, writeVersion, tls, impl);
|
||||
auto *n = *insert(&root, key, writeVersion, tls, impl);
|
||||
if (!n->entryPresent) {
|
||||
++tls->accum.entries_inserted;
|
||||
auto *p = nextLogical(n);
|
||||
@@ -3063,41 +3060,16 @@ void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
}
|
||||
++tls->accum.range_writes;
|
||||
const bool beginIsPrefix = lcp == int(begin.size());
|
||||
auto remaining = begin.subspan(0, lcp);
|
||||
|
||||
auto *n = root;
|
||||
Node **useAsRoot =
|
||||
insert(&root, begin.subspan(0, lcp), writeVersion, tls, impl);
|
||||
|
||||
for (;;) {
|
||||
if (int(remaining.size()) <= n->partialKeyLen) {
|
||||
break;
|
||||
}
|
||||
int i = longestCommonPrefix(n->partialKey(), remaining.data(),
|
||||
n->partialKeyLen);
|
||||
if (i != n->partialKeyLen) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto *child = getChild(n, remaining[n->partialKeyLen]);
|
||||
if (child == nullptr) {
|
||||
break;
|
||||
}
|
||||
|
||||
assert(maxVersion(n, impl) <= writeVersion);
|
||||
setMaxVersion(n, impl, writeVersion);
|
||||
|
||||
remaining = remaining.subspan(n->partialKeyLen + 1,
|
||||
remaining.size() - (n->partialKeyLen + 1));
|
||||
n = child;
|
||||
}
|
||||
|
||||
Node **useAsRoot = &getInTree(n, impl);
|
||||
|
||||
int consumed = lcp - remaining.size();
|
||||
int consumed = lcp;
|
||||
|
||||
begin = begin.subspan(consumed, begin.size() - consumed);
|
||||
end = end.subspan(consumed, end.size() - consumed);
|
||||
|
||||
auto *beginNode = insert(useAsRoot, begin, writeVersion, tls, impl);
|
||||
auto *beginNode = *insert(useAsRoot, begin, writeVersion, tls, impl);
|
||||
|
||||
const bool insertedBegin = !beginNode->entryPresent;
|
||||
|
||||
@@ -3114,7 +3086,7 @@ void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
assert(writeVersion >= beginNode->entry.pointVersion);
|
||||
beginNode->entry.pointVersion = writeVersion;
|
||||
|
||||
auto *endNode = insert(useAsRoot, end, writeVersion, tls, impl);
|
||||
auto *endNode = *insert(useAsRoot, end, writeVersion, tls, impl);
|
||||
|
||||
const bool insertedEnd = !endNode->entryPresent;
|
||||
|
||||
@@ -3132,7 +3104,7 @@ void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
if (beginIsPrefix && insertedEnd) {
|
||||
// beginNode may have been invalidated when inserting end. TODO can we do
|
||||
// better?
|
||||
beginNode = insert(useAsRoot, begin, writeVersion, tls, impl);
|
||||
beginNode = *insert(useAsRoot, begin, writeVersion, tls, impl);
|
||||
assert(beginNode->entryPresent);
|
||||
}
|
||||
|
||||
@@ -3246,6 +3218,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
InternalVersionT::zero = tls.zero = oldestVersion;
|
||||
|
||||
assert(writeVersion >= newestVersionFullPrecision);
|
||||
assert(tls.accum.entries_erased == 0);
|
||||
assert(tls.accum.entries_inserted == 0);
|
||||
|
||||
if (oldestExtantVersion < writeVersion - kMaxCorrectVersionWindow)
|
||||
[[unlikely]] {
|
||||
@@ -3273,15 +3247,20 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
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);
|
||||
if (w.end.len > 0) {
|
||||
keyUpdates += 3;
|
||||
addWriteRange(root, begin, end, InternalVersionT(writeVersion), &tls,
|
||||
this);
|
||||
} else {
|
||||
keyUpdates += 2;
|
||||
addPointWrite(root, begin, InternalVersionT(writeVersion), &tls, this);
|
||||
}
|
||||
}
|
||||
|
||||
// Run gc at least 150% the rate we're inserting entries
|
||||
keyUpdates +=
|
||||
(std::max<int64_t>(
|
||||
tls.accum.entries_inserted - tls.accum.entries_erased, 0) *
|
||||
3) >>
|
||||
1;
|
||||
|
||||
memory_bytes.set(totalBytes);
|
||||
point_writes_total.add(tls.accum.point_writes);
|
||||
range_writes_total.add(tls.accum.range_writes);
|
||||
|
||||
@@ -76,6 +76,14 @@ void workload(weaselab::ConflictSet *cs) {
|
||||
} else {
|
||||
w.begin.len = k.size();
|
||||
cs->addWrites(&w, 1, version);
|
||||
int64_t beginN = version - kWindowSize + rand() % kWindowSize;
|
||||
auto b = numToKey(beginN);
|
||||
auto e = numToKey(beginN + 1000);
|
||||
w.begin.p = b.data();
|
||||
w.begin.len = b.size();
|
||||
w.end.p = e.data();
|
||||
w.end.len = e.size();
|
||||
cs->addWrites(&w, 1, version);
|
||||
}
|
||||
}
|
||||
// GC
|
||||
|
||||
Reference in New Issue
Block a user