eraseBetween optimizations

This commit is contained in:
2024-08-14 16:13:37 -07:00
parent 1e34951a77
commit e64ebabced

View File

@@ -1808,13 +1808,15 @@ void eraseBetween(Node **inTree, Node16 *n, int begin, int end,
} }
n->numChildren = nodeOut - n->children; n->numChildren = nodeOut - n->children;
if (n->numChildren == 0) { if (n->numChildren > Node3::kMaxNodes) {
auto *newNode = tls->allocate<Node0>(n->partialKeyLen); // nop
} else if (n->numChildren > 0) {
auto *newNode = tls->allocate<Node3>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
} else if (n->numChildren <= Node3::kMaxNodes) { } else {
auto *newNode = tls->allocate<Node3>(n->partialKeyLen); auto *newNode = tls->allocate<Node0>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
@@ -1850,18 +1852,20 @@ void eraseBetween(Node **inTree, Node48 *n, int begin, int end,
} }
n->numChildren = n->nextFree; n->numChildren = n->nextFree;
if (n->numChildren == 0) { if (n->numChildren > Node16::kMaxNodes) {
auto *newNode = tls->allocate<Node0>(n->partialKeyLen); // nop
} else if (n->numChildren > Node3::kMaxNodes) {
auto *newNode = tls->allocate<Node16>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
} else if (n->numChildren <= Node3::kMaxNodes) { } else if (n->numChildren > 0) {
auto *newNode = tls->allocate<Node3>(n->partialKeyLen); auto *newNode = tls->allocate<Node3>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
} else if (n->numChildren <= Node16::kMaxNodes) { } else {
auto *newNode = tls->allocate<Node16>(n->partialKeyLen); auto *newNode = tls->allocate<Node0>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
@@ -1870,38 +1874,32 @@ void eraseBetween(Node **inTree, Node48 *n, int begin, int end,
void eraseBetween(Node **inTree, Node256 *n, int begin, int end, void eraseBetween(Node **inTree, Node256 *n, int begin, int end,
WriteContext *tls) { WriteContext *tls) {
const unsigned shiftUpperBound = end - begin; for (int i = n->bitSet.firstSetGeq(begin); i >= 0 && i < end;
const unsigned shiftAmount = begin; i = n->bitSet.firstSetGeq(i)) {
auto inBounds = [&](unsigned c) { return c - shiftAmount < shiftUpperBound; }; assert(n->children[i] != nullptr);
n->numChildren = 0; eraseTree(std::exchange(n->children[i], nullptr), tls);
BitSet newBitSet{}; n->bitSet.reset(i);
n->bitSet.forEachSet([&](int i) { --n->numChildren;
if (inBounds(i)) { }
eraseTree(std::exchange(n->children[i], nullptr), tls); if (n->numChildren > Node48::kMaxNodes) {
} else { // nop
++n->numChildren; } else if (n->numChildren > Node16::kMaxNodes) {
newBitSet.set(i); auto *newNode = tls->allocate<Node48>(n->partialKeyLen);
}
});
n->bitSet = newBitSet;
// Don't need to update childMaxVersion or maxOfMax because of monotonicity
if (n->numChildren == 0) {
auto *newNode = tls->allocate<Node0>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
} else if (n->numChildren <= Node3::kMaxNodes) { } else if (n->numChildren > Node3::kMaxNodes) {
auto *newNode = tls->allocate<Node3>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n);
tls->release(n);
*inTree = newNode;
} else if (n->numChildren <= Node16::kMaxNodes) {
auto *newNode = tls->allocate<Node16>(n->partialKeyLen); auto *newNode = tls->allocate<Node16>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;
} else if (n->numChildren <= Node48::kMaxNodes) { } else if (n->numChildren > 0) {
auto *newNode = tls->allocate<Node48>(n->partialKeyLen); auto *newNode = tls->allocate<Node3>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n);
tls->release(n);
*inTree = newNode;
} else {
auto *newNode = tls->allocate<Node0>(n->partialKeyLen);
newNode->copyChildrenAndKeyFrom(*n); newNode->copyChildrenAndKeyFrom(*n);
tls->release(n); tls->release(n);
*inTree = newNode; *inTree = newNode;