@@ -718,10 +718,23 @@ void maybeDownsize(Node *self, Node *&root, NodeAllocators *allocators,
|
||||
switch (self->type) {
|
||||
case Type::Node0:
|
||||
__builtin_unreachable(); // GCOVR_EXCL_LINE
|
||||
case Type::Node4:
|
||||
if (self->numChildren < 2) {
|
||||
case Type::Node4: {
|
||||
auto *self4 = (Node4 *)self;
|
||||
if (self->numChildren == 0) {
|
||||
auto *newSelf = allocators->node0.allocate(self->partialKeyLen);
|
||||
memcpy((char *)newSelf + kNodeCopyBegin, (char *)self + kNodeCopyBegin,
|
||||
kNodeCopySize);
|
||||
memcpy(newSelf->partialKey(), self4->partialKey(), self->partialKeyLen);
|
||||
|
||||
if (self->parent == nullptr) {
|
||||
root = newSelf;
|
||||
} else {
|
||||
getChildExists(self->parent, self->parentsIndex) = newSelf;
|
||||
}
|
||||
|
||||
allocators->node4.release(self4);
|
||||
} else if (self->numChildren == 1) {
|
||||
if (!self->entryPresent) {
|
||||
auto *self4 = (Node4 *)self;
|
||||
auto *child = self4->children[0].child;
|
||||
int minCapacity = self4->partialKeyLen + 1 + child->partialKeyLen;
|
||||
|
||||
@@ -763,7 +776,7 @@ void maybeDownsize(Node *self, Node *&root, NodeAllocators *allocators,
|
||||
allocators->node4.release(self4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case Type::Node16:
|
||||
if (self->numChildren < kMinChildrenNode16) {
|
||||
auto *self16 = (Node16 *)self;
|
||||
@@ -2365,6 +2378,39 @@ Iterator firstGeq(Node *n, std::string_view key) {
|
||||
return total;
|
||||
}
|
||||
|
||||
[[maybe_unused]] void checkMinChildCount(Node *node, bool &success) {
|
||||
int minNumChildren;
|
||||
switch (node->type) {
|
||||
case Type::Node0:
|
||||
minNumChildren = 0;
|
||||
break;
|
||||
case Type::Node4:
|
||||
minNumChildren = kMinChildrenNode4;
|
||||
break;
|
||||
case Type::Node16:
|
||||
minNumChildren = kMinChildrenNode16;
|
||||
break;
|
||||
case Type::Node48:
|
||||
minNumChildren = kMinChildrenNode48;
|
||||
break;
|
||||
case Type::Node256:
|
||||
minNumChildren = kMinChildrenNode256;
|
||||
break;
|
||||
}
|
||||
if (node->numChildren < minNumChildren) {
|
||||
Arena arena;
|
||||
fprintf(stderr,
|
||||
"%s has %d children, which is less than the minimum required %d\n",
|
||||
getSearchPathPrintable(node).c_str(), node->numChildren,
|
||||
minNumChildren);
|
||||
success = false;
|
||||
}
|
||||
for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) {
|
||||
auto *child = getChildExists(node, i);
|
||||
checkMinChildCount(child, success);
|
||||
}
|
||||
}
|
||||
|
||||
bool checkCorrectness(Node *node, int64_t oldestVersion,
|
||||
ConflictSet::Impl *impl) {
|
||||
bool success = true;
|
||||
@@ -2372,6 +2418,7 @@ bool checkCorrectness(Node *node, int64_t oldestVersion,
|
||||
checkParentPointers(node, success);
|
||||
checkMaxVersion(node, node, oldestVersion, success, impl);
|
||||
checkEntriesExist(node, success);
|
||||
checkMinChildCount(node, success);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
Reference in New Issue
Block a user