capability_skeleton/
tree_level_specific_measurer.rs1crate::ix!();
3
4impl TreeLevelSpecificMeasurer for Skeleton {
5 fn measure_tree_level_stats(&self) -> HashMap<u8, TreeLevelAggregate> {
6 let level_map = build_node_level_map(self);
7
8 #[derive(Default)]
9 struct TempLevelStats {
10 node_count: u64,
11 child_count: u64,
12 leaf_count: u64,
13 }
14 let mut accum = HashMap::<u8, TempLevelStats>::new();
15
16 for node in self.nodes() {
17 if let Some(&lvl) = level_map.get(&node.id()) {
18 let entry = accum.entry(lvl).or_insert_with(TempLevelStats::default);
19 entry.node_count += 1;
20 entry.child_count += node.child_ids().len() as u64;
21 if node.child_ids().is_empty() {
22 entry.leaf_count += node.leaf_count() as u64;
23 }
24 }
25 }
26
27 let mut result = HashMap::new();
28 for (lvl, tmp) in accum {
29 let built = TreeLevelAggregateBuilder::default()
30 .total_node_count(tmp.node_count)
31 .total_child_count(tmp.child_count)
32 .total_leaf_count(tmp.leaf_count)
33 .build()
34 .unwrap();
35 result.insert(lvl, built);
36 }
37 result
38 }
39}
40
41#[cfg(test)]
42mod skeleton_level_specific_measurer_assessment {
43 use super::*;
44
45 #[traced_test]
46 fn check_level_stats_with_branching() {
47 let root = SkeletonNodeBuilder::default()
49 .id(0_u16)
50 .child_ids(vec![1,2])
51 .name("root")
52 .original_key("root")
53 .build(NodeKind::Dispatch)
54 .unwrap();
55 let child_a = SkeletonNodeBuilder::default()
56 .id(1_u16)
57 .child_ids(vec![3])
58 .name("childA")
59 .original_key("childA")
60 .build(NodeKind::Dispatch)
61 .unwrap();
62 let child_b = SkeletonNodeBuilder::default()
63 .id(2_u16)
64 .leaf_count(2_u16)
65 .name("childB")
66 .original_key("childB")
67 .build(NodeKind::LeafHolder)
68 .unwrap();
69 let child_c = SkeletonNodeBuilder::default()
70 .id(3_u16)
71 .leaf_count(3_u16)
72 .name("childC")
73 .original_key("childC")
74 .build(NodeKind::LeafHolder)
75 .unwrap();
76
77 let skel = SkeletonBuilder::default()
78 .nodes(vec![root, child_a, child_b, child_c])
79 .root_id(Some(0))
80 .build()
81 .unwrap();
82
83 let level_stats = skel.measure_tree_level_stats();
84
85 let agg0 = level_stats.get(&0).unwrap();
90 assert_eq!(*agg0.total_node_count(), 1);
91 assert_eq!(*agg0.total_child_count(), 2);
92 assert_eq!(*agg0.total_leaf_count(), 0);
93
94 let agg1 = level_stats.get(&1).unwrap();
95 assert_eq!(*agg1.total_node_count(), 2);
96 assert_eq!(*agg1.total_child_count(), 1); assert_eq!(*agg1.total_leaf_count(), 2);
98
99 let agg2 = level_stats.get(&2).unwrap();
100 assert_eq!(*agg2.total_node_count(), 1);
101 assert_eq!(*agg2.total_child_count(), 0);
102 assert_eq!(*agg2.total_leaf_count(), 3);
103 }
104
105 #[traced_test]
106 fn check_level_stats_in_linear_chain() {
107 let n0 = SkeletonNodeBuilder::default()
110 .id(0u16)
111 .child_ids(vec![1u16])
112 .name("root")
113 .original_key("root")
114 .build(NodeKind::Dispatch)
115 .unwrap();
116 let n1 = SkeletonNodeBuilder::default()
117 .id(1u16)
118 .child_ids(vec![2u16])
119 .name("child")
120 .original_key("child")
121 .build(NodeKind::Dispatch)
122 .unwrap();
123 let n2 = SkeletonNodeBuilder::default()
124 .id(2u16)
125 .leaf_count(4u16)
126 .name("grandchild")
127 .original_key("grandchild")
128 .build(NodeKind::LeafHolder)
129 .unwrap();
130
131 let skel = SkeletonBuilder::default()
132 .nodes(vec![n0, n1, n2])
133 .root_id(Some(0u16))
134 .build()
135 .unwrap();
136
137 let level_stats = skel.measure_tree_level_stats();
138
139 let agg0 = level_stats.get(&0).unwrap();
143 assert_eq!(*agg0.total_node_count(), 1);
144 assert_eq!(*agg0.total_child_count(), 1);
145 assert_eq!(*agg0.total_leaf_count(), 0);
146
147 let agg1 = level_stats.get(&1).unwrap();
148 assert_eq!(*agg1.total_node_count(), 1);
149 assert_eq!(*agg1.total_child_count(), 1);
150 assert_eq!(*agg1.total_leaf_count(), 0);
151
152 let agg2 = level_stats.get(&2).unwrap();
153 assert_eq!(*agg2.total_node_count(), 1);
154 assert_eq!(*agg2.total_child_count(), 0);
155 assert_eq!(*agg2.total_leaf_count(), 4);
156 }
157}