Change PTreeImpl::insert to overwrite existing entries (#9138)

* Change PTreeImpl::insert to overwrite existing entries

Maintaining partial persistence of course.

We can theoretically also avoid creating a new node if the insert version of the node comparing equal to `x` is the latestVersion. There isn't a generic way to tell from the ptree though since insertAt is a concept that only exists within VersionedMap. Either way, avoiding the `contains` call and the tree rotations is already a big improvement.

The old node should only be reachable from old roots, and so it should get cleaned up as part of forgetVersions in the storage server.

* Update fdbclient/include/fdbclient/VersionedMap.h
This commit is contained in:
Andrew Noyes 2023-01-18 09:40:32 -08:00 committed by GitHub
parent e3c3922cc5
commit 1c673326e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 10 deletions

View File

@ -285,12 +285,17 @@ void insert(Reference<PTree<T>>& p, Version at, const T& x) {
if (!p) {
p = makeReference<PTree<T>>(x, at);
} else {
bool direction = !(x < p->data);
Reference<PTree<T>> child = p->child(direction, at);
insert(child, at, x);
p = update(p, direction, child, at);
if (p->child(direction, at)->priority > p->priority)
rotate(p, at, !direction);
int c = ::compare(x, p->data);
if (c == 0) {
p = makeReference<PTree<T>>(p->priority, x, p->left(at), p->right(at), at);
} else {
const bool direction = !(c < 0);
Reference<PTree<T>> child = p->child(direction, at);
insert(child, at, x);
p = update(p, direction, child, at);
if (p->child(direction, at)->priority > p->priority)
rotate(p, at, !direction);
}
}
}
@ -732,10 +737,6 @@ public:
// insert() and erase() invalidate atLatest() and all iterators into it
void insert(const K& k, const T& t) { insert(k, t, latestVersion); }
void insert(const K& k, const T& t, Version insertAt) {
if (PTreeImpl::contains(roots.back().second, latestVersion, k))
PTreeImpl::remove(roots.back().second,
latestVersion,
k); // FIXME: Make PTreeImpl::insert do this automatically (see also WriteMap.h FIXME)
PTreeImpl::insert(
roots.back().second, latestVersion, MapPair<K, std::pair<T, Version>>(k, std::make_pair(t, insertAt)));
}

View File

@ -90,6 +90,8 @@ struct WriteMapEntry {
int compare(ExtStringRef const& r) const { return -r.compare(key); }
int compare(WriteMapEntry const& r) const { return key.compare(r.key); }
std::string toString() const { return printable(key); }
};