Enforce that root does not have a partial key
This commit is contained in:
@@ -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);
|
||||||
|
Reference in New Issue
Block a user