From 7e49888becd9e93dab5e5cb59f2ce414ad73e213 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Wed, 14 Aug 2024 16:40:29 -0700 Subject: [PATCH] More eraseBetween optimizations --- ConflictSet.cpp | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 5d11e62..19b4793 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -1825,32 +1825,28 @@ void eraseBetween(Node **inTree, Node16 *n, int begin, int end, void eraseBetween(Node **inTree, Node48 *n, int begin, int end, WriteContext *tls) { - const unsigned shiftUpperBound = end - begin; - const unsigned shiftAmount = begin; - auto inBounds = [&](unsigned c) { return c - shiftAmount < shiftUpperBound; }; - Node **nodeOut = n->children; - uint8_t *indexOut = n->reverseIndex; - InternalVersionT *maxVOut = n->childMaxVersion; - for (auto &v : n->maxOfMax) { - v = tls->zero; - } - n->bitSet = {}; - memset(n->index, -1, sizeof(n->index)); - n->nextFree = 0; - for (int i = 0; i < n->numChildren; ++i) { - if (inBounds(n->reverseIndex[i])) { - eraseTree(n->children[i], tls); - } else { - *nodeOut++ = n->children[i]; - *indexOut++ = n->reverseIndex[i]; - *maxVOut++ = n->childMaxVersion[i]; - n->maxOfMax[i >> Node48::kMaxOfMaxShift] = std::max( - n->maxOfMax[i >> Node48::kMaxOfMaxShift], n->childMaxVersion[i]); - n->bitSet.set(n->reverseIndex[i]); - n->index[n->reverseIndex[i]] = n->nextFree++; + for (int i = n->bitSet.firstSetGeq(begin); i >= 0 && i < end; + i = n->bitSet.firstSetGeq(i)) { + n->bitSet.reset(i); + int8_t toRemoveChildrenIndex = std::exchange(n->index[i], -1); + int8_t lastChildrenIndex = --n->nextFree; + assert(toRemoveChildrenIndex >= 0); + assert(lastChildrenIndex >= 0); + eraseTree(n->children[toRemoveChildrenIndex], tls); + if (toRemoveChildrenIndex != lastChildrenIndex) { + n->children[toRemoveChildrenIndex] = n->children[lastChildrenIndex]; + n->childMaxVersion[toRemoveChildrenIndex] = + n->childMaxVersion[lastChildrenIndex]; + n->maxOfMax[toRemoveChildrenIndex >> Node48::kMaxOfMaxShift] = + std::max(n->maxOfMax[toRemoveChildrenIndex >> Node48::kMaxOfMaxShift], + n->childMaxVersion[toRemoveChildrenIndex]); + auto parentIndex = n->children[toRemoveChildrenIndex]->parentsIndex; + n->index[parentIndex] = toRemoveChildrenIndex; + n->reverseIndex[toRemoveChildrenIndex] = parentIndex; } + n->childMaxVersion[lastChildrenIndex] = tls->zero; + --n->numChildren; } - n->numChildren = n->nextFree; if (n->numChildren > Node16::kMaxNodes) { // nop