Prepare for erase to invalidate children of parent

This commit is contained in:
2024-03-12 15:54:21 -07:00
parent b0ac7e41b9
commit aefb83dbc6

View File

@@ -829,7 +829,7 @@ void maybeDecreaseCapacity(Node *&self, NodeAllocators *allocators,
// TODO fuse into erase child so we don't need to repeat branches on type // TODO fuse into erase child so we don't need to repeat branches on type
void maybeDownsize(Node *self, NodeAllocators *allocators, void maybeDownsize(Node *self, NodeAllocators *allocators,
ConflictSet::Impl *impl) { ConflictSet::Impl *impl, Node *&dontInvalidate) {
switch (self->type) { switch (self->type) {
case Type::Node0: case Type::Node0:
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
@@ -954,7 +954,8 @@ void maybeDownsize(Node *self, NodeAllocators *allocators,
} }
// Precondition: self is not the root. May invalidate nodes along the search // Precondition: self is not the root. May invalidate nodes along the search
// path to self. // path to self. May invalidate children of self->parent. Returns a pointer to
// the node after self.
Node *erase(Node *self, NodeAllocators *allocators, ConflictSet::Impl *impl) { Node *erase(Node *self, NodeAllocators *allocators, ConflictSet::Impl *impl) {
assert(self->parent != nullptr); assert(self->parent != nullptr);
@@ -1019,7 +1020,7 @@ Node *erase(Node *self, NodeAllocators *allocators, ConflictSet::Impl *impl) {
parent->parent != nullptr) { parent->parent != nullptr) {
erase(parent, allocators, impl); erase(parent, allocators, impl);
} else { } else {
maybeDownsize(parent, allocators, impl); maybeDownsize(parent, allocators, impl, result);
} }
return result; return result;
} }
@@ -2014,8 +2015,14 @@ void addWriteRange(Node *&root, int64_t oldestVersion,
assert(beginNode->entryPresent); assert(beginNode->entryPresent);
} }
for (beginNode = nextLogical(beginNode); beginNode != endNode; for (beginNode = nextLogical(beginNode); beginNode != endNode;) {
beginNode = erase(beginNode, allocators, impl)) { auto *next = nextLogical(beginNode);
bool done = next == endNode;
erase(beginNode, allocators, impl);
if (done) {
break;
}
beginNode = next;
} }
} }