diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 15889d8..841787e 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -291,8 +291,6 @@ struct Node { int32_t partialKeyLen; int16_t numChildren; bool entryPresent; - // Temp variable used to signal the end of the range during addWriteRange - bool endOfRange; uint8_t parentsIndex; /* end section that's copied to the next node */ @@ -699,7 +697,6 @@ template struct NodeAllocator { T *allocate(int capacity) { T *result = allocate_helper(capacity); - result->endOfRange = false; result->releaseDeferred = false; if constexpr (!std::is_same_v) { const auto z = InternalVersionT::zero; @@ -2976,18 +2973,19 @@ AddedWriteRange addWriteRange(Node *beginRoot, TrivialSpan begin, Node *endRoot, void eraseInRange(Node *beginNode, Node *endNode, WriteContext *writeContext, ConflictSet::Impl *impl) { + auto checkNodesEq = [](Node *lhs, Node *&rhs) { + assert(!lhs->releaseDeferred); + while (rhs->releaseDeferred) [[unlikely]] { + rhs = rhs->forwardTo; + } + return lhs == rhs; + }; + // Erase nodes in range - assert(!beginNode->endOfRange); - assert(!endNode->endOfRange); - endNode->endOfRange = true; - Node *iter = beginNode; - for (iter = nextLogical(iter); !iter->endOfRange; + Node *iter = nextLogical(beginNode); + for (; !checkNodesEq(iter, endNode); iter = erase(iter, writeContext, impl, /*logical*/ true)) { - assert(!iter->endOfRange); - assert(!iter->releaseDeferred); } - assert(iter->endOfRange); - iter->endOfRange = false; // Inserting end trashed the last node's maxVersion. Fix that. Safe to call // since the end key always has non-zero size.