Skip to content

Commit

Permalink
Merge pull request #3 from dqnykamp/simplify_compactify
Browse files Browse the repository at this point in the history
simplify compactify algorithm
  • Loading branch information
siefkenj authored Feb 8, 2024
2 parents f608205 + 91c0a9a commit 4eff0f3
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ fn can_compactify() {
// Add several nodes that aren't connected to the root
flat_root.merge_content(&dast_root2.children[0], Some(0));
flat_root.children = vec![UntaggedContent::Ref(2), UntaggedContent::Ref(3)];
flat_root.nodes[2].set_parent(None);
flat_root.nodes[3].set_parent(None);
flat_root.compactify();

assert_json_eq!(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl FlatNode {
if let Some(parent) = &mut elm.parent {
*parent = ref_index_map[*parent];
}
elm.idx = ref_index_map[elm.idx];
}
FlatNode::FunctionMacro(function_macro) => {
if let Some(inputs) = &mut function_macro.input {
Expand All @@ -71,16 +72,19 @@ impl FlatNode {
if let Some(parent) = &mut function_macro.parent {
*parent = ref_index_map[*parent];
}
function_macro.idx = ref_index_map[function_macro.idx];
}
FlatNode::Macro(macro_) => {
if let Some(parent) = &mut macro_.parent {
*parent = ref_index_map[*parent];
}
macro_.idx = ref_index_map[macro_.idx];
}
FlatNode::Error(err) => {
if let Some(parent) = &mut err.parent {
*parent = ref_index_map[*parent];
}
err.idx = ref_index_map[err.idx];
}
}
}
Expand Down Expand Up @@ -130,6 +134,8 @@ impl FlatRoot {
})
.collect::<Vec<_>>();

self.nodes.retain(|node| is_referenced[node.idx()]);

// Shift the indices of all nodes and the references of the root node
self.nodes
.iter_mut()
Expand All @@ -139,46 +145,5 @@ impl FlatRoot {
*idx = old_to_new_indices[*idx];
}
});

// Make sure that the locally stored index on each node is correct.
// A node may have an inconsistent index if it was manually inserted.
self.recompute_indices();
self.nodes.retain(|node| is_referenced[node.idx()]);

// Clean up the indices of the nodes
self.recompute_indices();
self.recompute_parents();
}

/// Make sure that every node has an index equal to its position in the `nodes`
/// array. This is used for ensuring a consistent state after manual manipulation.
fn recompute_indices(&mut self) {
self.nodes.iter_mut().enumerate().for_each(|(idx, node)| {
node.set_idx(idx);
});
}

/// Recompute the parent of each node. Only nodes that are reachable from `self.children`
/// are considered. This is used to ensure consistency after manual manipulation.
fn recompute_parents(&mut self) {
struct Pair {
ref_idx: Index,
parent: Option<Index>,
}
let mut stack = Vec::from_iter(self.children.iter().filter_map(|child| match child {
UntaggedContent::Ref(idx) => Some(Pair {
ref_idx: *idx,
parent: None,
}),
_ => None,
}));
while let Some(pair) = stack.pop() {
let node = &mut self.nodes[pair.ref_idx];
node.set_parent(pair.parent);
stack.extend(node.all_references().iter().map(|idx| Pair {
ref_idx: *idx,
parent: Some(pair.ref_idx),
}));
}
}
}

0 comments on commit 4eff0f3

Please sign in to comment.