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