destroyTree -> eraseTree. Use freelist

This commit is contained in:
2024-08-14 14:47:22 -07:00
parent 4b82502946
commit b7f9084694

View File

@@ -1715,50 +1715,50 @@ void maybeDownsize(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
} }
} }
void destroyTree(Node *root, WriteContext::Accum *accum) { void eraseTree(Node *root, WriteContext *tls) {
Arena arena; Arena arena;
auto toFree = vector<Node *>(arena); auto toFree = vector<Node *>(arena);
toFree.push_back(root); toFree.push_back(root);
#if SHOW_MEMORY
for (auto *iter = root; iter != nullptr; iter = nextPhysical(iter)) {
removeNode(iter);
removeKey(iter);
}
#endif
while (toFree.size() > 0) { while (toFree.size() > 0) {
auto *n = toFree.back(); auto *n = toFree.back();
toFree.pop_back(); toFree.pop_back();
accum->entries_erased += n->entryPresent; tls->accum.entries_erased += n->entryPresent;
++accum->nodes_released; ++tls->accum.nodes_released;
removeNode(n);
removeKey(n);
switch (n->getType()) { switch (n->getType()) {
case Type_Node0: { case Type_Node0: {
auto *n0 = static_cast<Node0 *>(n);
tls->release(n0);
} break; } break;
case Type_Node3: { case Type_Node3: {
auto *n3 = static_cast<Node3 *>(n); auto *n3 = static_cast<Node3 *>(n);
toFree.append(std::span<Node *>(n3->children, n3->numChildren)); toFree.append(std::span<Node *>(n3->children, n3->numChildren));
tls->release(n3);
} break; } break;
case Type_Node16: { case Type_Node16: {
auto *n16 = static_cast<Node16 *>(n); auto *n16 = static_cast<Node16 *>(n);
toFree.append(std::span<Node *>(n16->children, n16->numChildren)); toFree.append(std::span<Node *>(n16->children, n16->numChildren));
tls->release(n16);
} break; } break;
case Type_Node48: { case Type_Node48: {
auto *n48 = static_cast<Node48 *>(n); auto *n48 = static_cast<Node48 *>(n);
toFree.append(std::span<Node *>(n48->children, n48->numChildren)); toFree.append(std::span<Node *>(n48->children, n48->numChildren));
tls->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(); auto *out = toFree.unsafePrepareAppend(n256->numChildren).data();
n256->bitSet.forEachSet([&](int i) { *out++ = n256->children[i]; }); n256->bitSet.forEachSet([&](int i) { *out++ = n256->children[i]; });
assert(out == toFree.end()); assert(out == toFree.end());
tls->release(n256);
} break; } break;
default: // GCOVR_EXCL_LINE default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
} }
removeNode(n);
safe_free(n, n->size());
} }
} }
@@ -1772,7 +1772,7 @@ void eraseBetween(Node3 *&n, int begin, int end, WriteContext *tls,
InternalVersionT *maxVOut = n->childMaxVersion; InternalVersionT *maxVOut = n->childMaxVersion;
for (int i = 0; i < n->numChildren; ++i) { for (int i = 0; i < n->numChildren; ++i) {
if (inBounds(n->index[i])) { if (inBounds(n->index[i])) {
destroyTree(n->children[i], &tls->accum); eraseTree(n->children[i], tls);
} else { } else {
*nodeOut++ = n->children[i]; *nodeOut++ = n->children[i];
*indexOut++ = n->index[i]; *indexOut++ = n->index[i];
@@ -1800,7 +1800,7 @@ void eraseBetween(Node16 *&n, int begin, int end, WriteContext *tls,
InternalVersionT *maxVOut = n->childMaxVersion; InternalVersionT *maxVOut = n->childMaxVersion;
for (int i = 0; i < n->numChildren; ++i) { for (int i = 0; i < n->numChildren; ++i) {
if (inBounds(n->index[i])) { if (inBounds(n->index[i])) {
destroyTree(n->children[i], &tls->accum); eraseTree(n->children[i], tls);
} else { } else {
*nodeOut++ = n->children[i]; *nodeOut++ = n->children[i];
*indexOut++ = n->index[i]; *indexOut++ = n->index[i];
@@ -1840,7 +1840,7 @@ void eraseBetween(Node48 *&n, int begin, int end, WriteContext *tls,
n->nextFree = 0; n->nextFree = 0;
for (int i = 0; i < n->numChildren; ++i) { for (int i = 0; i < n->numChildren; ++i) {
if (inBounds(n->reverseIndex[i])) { if (inBounds(n->reverseIndex[i])) {
destroyTree(n->children[i], &tls->accum); eraseTree(n->children[i], tls);
} else { } else {
*nodeOut++ = n->children[i]; *nodeOut++ = n->children[i];
*indexOut++ = n->reverseIndex[i]; *indexOut++ = n->reverseIndex[i];
@@ -1883,7 +1883,7 @@ void eraseBetween(Node256 *&n, int begin, int end, WriteContext *tls,
BitSet newBitSet; BitSet newBitSet;
n->bitSet.forEachSet([&](int i) { n->bitSet.forEachSet([&](int i) {
if (inBounds(i)) { if (inBounds(i)) {
destroyTree(std::exchange(n->children[i], nullptr), &tls->accum); eraseTree(std::exchange(n->children[i], nullptr), tls);
} else { } else {
++n->numChildren; ++n->numChildren;
newBitSet.set(i); newBitSet.set(i);
@@ -3412,7 +3412,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
if (oldestExtantVersion < writeVersion - kMaxCorrectVersionWindow) if (oldestExtantVersion < writeVersion - kMaxCorrectVersionWindow)
[[unlikely]] { [[unlikely]] {
if (writeVersion > newestVersionFullPrecision + kNominalVersionWindow) { if (writeVersion > newestVersionFullPrecision + kNominalVersionWindow) {
destroyTree(root, &tls.accum); eraseTree(root, &tls);
init(writeVersion - kNominalVersionWindow); init(writeVersion - kNominalVersionWindow);
} }
@@ -3581,7 +3581,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
initMetrics(); initMetrics();
} }
~Impl() { ~Impl() {
destroyTree(root, &tls.accum); eraseTree(root, &tls);
safe_free(metrics, metricsCount * sizeof(metrics[0])); safe_free(metrics, metricsCount * sizeof(metrics[0]));
} }