Update eraseTree to account for leaves

This commit is contained in:
2024-11-22 18:27:45 -08:00
parent 8b71852495
commit 235938b5aa

View File

@@ -276,6 +276,8 @@ struct TaggedNodePointer {
__builtin_prefetch((void *)withoutType()); __builtin_prefetch((void *)withoutType());
} }
bool isLeaf() { return getType() > Type_Node256; }
private: private:
TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) { TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) {
assert((this->p & 15) == 0); assert((this->p & 15) == 0);
@@ -3069,6 +3071,12 @@ void eraseTree(Node *root, WriteContext *writeContext) {
removeKey(n); removeKey(n);
auto pushIfNotLeaf = [&toFree](TaggedNodePointer p) {
if (!p.isLeaf()) {
toFree.push_back(p);
}
};
switch (n->getType()) { switch (n->getType()) {
case Type_Node0: { case Type_Node0: {
auto *n0 = static_cast<Node0 *>(n); auto *n0 = static_cast<Node0 *>(n);
@@ -3077,31 +3085,33 @@ void eraseTree(Node *root, WriteContext *writeContext) {
case Type_Node3: { case Type_Node3: {
auto *n3 = static_cast<Node3 *>(n); auto *n3 = static_cast<Node3 *>(n);
for (int i = 0; i < n3->numChildren; ++i) { for (int i = 0; i < n3->numChildren; ++i) {
toFree.push_back(n3->children[i]); pushIfNotLeaf(n3->children[i]);
} }
writeContext->release(n3); writeContext->release(n3);
} break; } break;
case Type_Node16: { case Type_Node16: {
auto *n16 = static_cast<Node16 *>(n); auto *n16 = static_cast<Node16 *>(n);
for (int i = 0; i < n16->numChildren; ++i) { for (int i = 0; i < n16->numChildren; ++i) {
toFree.push_back(n16->children[i]); pushIfNotLeaf(n16->children[i]);
} }
writeContext->release(n16); writeContext->release(n16);
} break; } break;
case Type_Node48: { case Type_Node48: {
auto *n48 = static_cast<Node48 *>(n); auto *n48 = static_cast<Node48 *>(n);
for (int i = 0; i < n48->numChildren; ++i) { for (int i = 0; i < n48->numChildren; ++i) {
toFree.push_back(n48->children[i]); pushIfNotLeaf(n48->children[i]);
} }
writeContext->release(n48); writeContext->release(n48);
} break; } break;
case Type_Node256: { case Type_Node256: {
auto *n256 = static_cast<Node256 *>(n); auto *n256 = static_cast<Node256 *>(n);
auto *out = toFree.unsafePrepareAppend(n256->numChildren).data(); n256->bitSet.forEachSet([&](int i) { pushIfNotLeaf(n256->children[i]); });
n256->bitSet.forEachSet([&](int i) { *out++ = n256->children[i]; });
assert(out == toFree.end());
writeContext->release(n256); writeContext->release(n256);
} break; } break;
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
} }