libreda_db/hierarchy/
util.rs1use super::traits::{HierarchyBase, HierarchyEdit};
9use fnv::FnvHashSet;
10
11pub trait HierarchyUtil: HierarchyBase {
14 fn is_top_level_cell(&self, cell: &Self::CellId) -> bool {
17 self.num_dependent_cells(cell) == 0
18 }
19
20 fn is_leaf_cell(&self, cell: &Self::CellId) -> bool {
23 self.num_cell_dependencies(cell) == 0
24 }
25
26 fn each_top_level_cell(&self) -> Box<dyn Iterator<Item = Self::CellId> + '_> {
28 Box::new(self.each_cell().filter(move |c| self.is_top_level_cell(c)))
29 }
30
31 fn each_leaf_cell(&self) -> Box<dyn Iterator<Item = Self::CellId> + '_> {
33 Box::new(self.each_cell().filter(move |c| self.is_leaf_cell(c)))
34 }
35
36 fn each_cell_bottom_to_top(&self) -> Box<dyn Iterator<Item = Self::CellId> + '_> {
38 let mut unsorted_cells: Vec<_> = self.each_cell_vec();
39 let mut visited_cells: FnvHashSet<_> = Default::default();
40 let mut sorted_cells = vec![];
41
42 unsorted_cells.retain(|cell| {
43 let all_dependencies_resolved = self
44 .each_cell_dependency(cell)
45 .all(|dependency| visited_cells.contains(&dependency));
46 if all_dependencies_resolved {
47 sorted_cells.push(cell.clone());
48 visited_cells.insert(cell.clone());
49 false
50 } else {
51 true
52 }
53 });
54
55 debug_assert!({
56 let mut is_topo_sorted = true;
57 for (i, cell) in sorted_cells.iter().enumerate() {
58 is_topo_sorted &= self
59 .each_cell_dependency(cell)
60 .all(|dependency| sorted_cells[0..i].contains(&dependency))
61 }
62 is_topo_sorted
63 });
64
65 Box::new(sorted_cells.into_iter())
66 }
67}
68
69impl<N: HierarchyBase> HierarchyUtil for N {}
70
71pub trait HierarchyEditUtil: HierarchyEdit {
74 fn clear_cell_instances(&mut self, cell: &Self::CellId) {
76 let child_instances = self.each_cell_instance_vec(cell);
77 for child in &child_instances {
78 self.remove_cell_instance(child);
79 }
80 }
81
82 fn prune_cell_instance(&mut self, inst: &Self::CellInstId) {
84 let template = self.template_cell(inst);
85 self.remove_cell_instance(inst);
86 if self.num_cell_references(&template) == 0 {
87 self.remove_cell(&template)
89 }
90 }
91
92 fn prune_cell(&mut self, cell: &Self::CellId) {
94 let child_instances = self.each_cell_instance_vec(cell);
95 for child in &child_instances {
96 self.prune_cell_instance(child);
97 }
98 self.remove_cell(cell)
99 }
100}
101
102impl<N: HierarchyEdit> HierarchyEditUtil for N {}