Skip to content

Commit

Permalink
fix: Optimize removal of unreachable nodes (#486)
Browse files Browse the repository at this point in the history
  • Loading branch information
mwcampbell authored Dec 8, 2024
1 parent d2bcd6d commit 93d0a72
Showing 1 changed file with 16 additions and 24 deletions.
40 changes: 16 additions & 24 deletions consumer/src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ impl State {
is_host_focused: bool,
mut changes: Option<&mut InternalChanges>,
) {
let mut orphans = HashSet::new();
let mut unreachable = HashSet::new();

if let Some(tree) = update.tree {
if tree.root != self.data.root {
orphans.insert(self.data.root);
unreachable.insert(self.data.root);
}
self.data = tree;
}
Expand Down Expand Up @@ -74,7 +74,7 @@ impl State {
for (node_id, node_data) in update.nodes {
let node_data = NodeData::from(node_data);

orphans.remove(&node_id);
unreachable.remove(&node_id);

let mut seen_child_ids = HashSet::with_capacity(node_data.children().len());
for (child_index, child_id) in node_data.children().iter().enumerate() {
Expand All @@ -84,7 +84,7 @@ impl State {
node_id.0, child_id.0
);
}
orphans.remove(child_id);
unreachable.remove(child_id);
let parent_and_index = ParentAndIndex(node_id, child_index);
if let Some(child_state) = self.nodes.get_mut_cow(child_id) {
if child_state.parent_and_index != Some(parent_and_index) {
Expand All @@ -110,7 +110,7 @@ impl State {
}
for child_id in node_state.data.children().iter() {
if !seen_child_ids.contains(child_id) {
orphans.insert(*child_id);
unreachable.insert(*child_id);
}
}
if *node_state.data != node_data {
Expand Down Expand Up @@ -144,31 +144,23 @@ impl State {
self.focus = update.focus;
self.is_host_focused = is_host_focused;

if !orphans.is_empty() {
let mut to_remove = Vec::new();

fn traverse_orphan(
nodes: &ChunkMap<NodeId, NodeState>,
to_remove: &mut Vec<NodeId>,
if !unreachable.is_empty() {
fn traverse_unreachable(
nodes: &mut ChunkMap<NodeId, NodeState>,
changes: &mut Option<&mut InternalChanges>,
id: NodeId,
) {
to_remove.push(id);
let node = nodes.get(&id).unwrap();
if let Some(changes) = changes {
changes.removed_node_ids.insert(id);
}
let node = nodes.remove_cow(&id).unwrap();
for child_id in node.data.children().iter() {
traverse_orphan(nodes, to_remove, *child_id);
traverse_unreachable(nodes, changes, *child_id);
}
}

for id in orphans {
traverse_orphan(&self.nodes, &mut to_remove, id);
}

for id in to_remove {
if self.nodes.remove_cow(&id).is_some() {
if let Some(changes) = &mut changes {
changes.removed_node_ids.insert(id);
}
}
for id in unreachable {
traverse_unreachable(&mut self.nodes, &mut changes, id);
}
}

Expand Down

0 comments on commit 93d0a72

Please sign in to comment.