Update eraseTree to account for leaves
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user