Enforce that root does not have a partial key

This commit is contained in:
2024-08-06 17:55:33 -07:00
parent 9b56a74b2f
commit 781ba15cae

View File

@@ -902,8 +902,7 @@ Node *&getChildExists(Node *self, uint8_t index) {
}
InternalVersionT maxVersion(Node *n, ConflictSet::Impl *);
InternalVersionT exchangeMaxVersion(Node *n, InternalVersionT newMax,
ConflictSet::Impl *);
InternalVersionT exchangeMaxVersion(Node *n, InternalVersionT newMax);
void setMaxVersion(Node *n, ConflictSet::Impl *, InternalVersionT maxVersion);
@@ -2925,8 +2924,9 @@ void consumePartialKey(Node *&self, std::span<const uint8_t> &key,
longestCommonPrefix(self->partialKey(), key.data(), commonLen);
if (partialKeyIndex < self->partialKeyLen) {
auto *old = self;
InternalVersionT oldMaxVersion =
exchangeMaxVersion(old, writeVersion, impl);
// Since root cannot have a partial key
assert(old->parent != nullptr);
InternalVersionT oldMaxVersion = exchangeMaxVersion(old, writeVersion);
// *self will have one child (old)
auto *newSelf = tls->allocate<Node3>(partialKeyIndex);
@@ -3596,13 +3596,11 @@ InternalVersionT maxVersion(Node *n, ConflictSet::Impl *impl) {
}
}
InternalVersionT exchangeMaxVersion(Node *n, InternalVersionT newMax,
ConflictSet::Impl *impl) {
// Precondition `n` is not the root
InternalVersionT exchangeMaxVersion(Node *n, InternalVersionT newMax) {
int index = n->parentsIndex;
n = n->parent;
if (n == nullptr) {
return std::exchange(impl->rootMaxVersion, newMax);
}
assert(n != nullptr);
switch (n->getType()) {
case Type_Node0: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
@@ -4141,6 +4139,10 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
ConflictSet::Impl *impl) {
bool success = true;
if (node->partialKeyLen > 0) {
fprintf(stderr, "Root cannot have a partial key");
success = false;
}
checkParentPointers(node, success);
checkMaxVersion(node, node, oldestVersion, success, impl);
checkEntriesExist(node, success);