Maintain childMaxVersion == 0 for unused children in Node48

This commit is contained in:
2024-06-26 20:16:50 -07:00
parent 789ecc29b3
commit 7d1d1d7b2a

View File

@@ -411,6 +411,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node16 &other) {
kNodeCopySize); kNodeCopySize);
assert(numChildren == Node16::kMaxNodes); assert(numChildren == Node16::kMaxNodes);
memset(index, -1, sizeof(index)); memset(index, -1, sizeof(index));
memset(children, 0, sizeof(children));
memcpy(partialKey(), &other + 1, partialKeyLen); memcpy(partialKey(), &other + 1, partialKeyLen);
bitSet.init(); bitSet.init();
nextFree = Node16::kMaxNodes; nextFree = Node16::kMaxNodes;
@@ -429,8 +430,10 @@ inline void Node48::copyChildrenAndKeyFrom(const Node16 &other) {
inline void Node48::copyChildrenAndKeyFrom(const Node48 &other) { inline void Node48::copyChildrenAndKeyFrom(const Node48 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize); kNodeCopySize);
memcpy(&bitSet, &other.bitSet, bitSet = other.bitSet;
sizeof(*this) - sizeof(Node) - sizeof(children)); nextFree = other.nextFree;
memcpy(index, other.index, sizeof(index));
memset(children, 0, sizeof(children));
for (int i = 0; i < numChildren; ++i) { for (int i = 0; i < numChildren; ++i) {
children[i] = other.children[i]; children[i] = other.children[i];
assert(children[i].child->parent == &other); assert(children[i].child->parent == &other);
@@ -444,6 +447,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node256 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin, memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize); kNodeCopySize);
memset(index, -1, sizeof(index)); memset(index, -1, sizeof(index));
memset(children, 0, sizeof(children));
nextFree = other.numChildren; nextFree = other.numChildren;
bitSet = other.bitSet; bitSet = other.bitSet;
int i = 0; int i = 0;
@@ -1356,6 +1360,7 @@ Node *erase(Node *self, NodeAllocators *allocators, ConflictSet::Impl *impl,
parent48->index[parentIndex] = toRemoveChildrenIndex; parent48->index[parentIndex] = toRemoveChildrenIndex;
parent48->reverseIndex[toRemoveChildrenIndex] = parentIndex; parent48->reverseIndex[toRemoveChildrenIndex] = parentIndex;
} }
parent48->children[lastChildrenIndex].childMaxVersion = 0;
--parent->numChildren; --parent->numChildren;
@@ -1708,8 +1713,9 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end,
bool conflict[Node48::kMaxNodes] = {}; bool conflict[Node48::kMaxNodes] = {};
assume(self->numChildren >= kMinChildrenNode48 - 1 /* entry present */); assume(self->numChildren >= kMinChildrenNode48 - 1 /* entry present */);
assume(self->numChildren <= Node48::kMaxNodes); assume(self->numChildren <= Node48::kMaxNodes);
for (int i = 0; i < self->numChildren; ++i) { for (int i = 0; i < Node48::kMaxNodes; ++i) {
assert(self->index[self->reverseIndex[i]] == i); assert(i >= self->numChildren || self->index[self->reverseIndex[i]] == i);
assert(i < self->numChildren || self->children[i].childMaxVersion == 0);
conflict[i] = (self->children[i].childMaxVersion > readVersion) & conflict[i] = (self->children[i].childMaxVersion > readVersion) &
inBounds(self->reverseIndex[i]); inBounds(self->reverseIndex[i]);
} }