crate::ix!();
impl TreeLevelSkippingMeasurer for Skeleton {
fn measure_tree_level_skipping(&self) -> HashMap<u8, TreeLevelSkippingStats> {
let level_map = build_node_level_map(self);
#[derive(Default)]
struct TempSkipStats {
node_count: u64,
leaf_count: u64,
}
let mut level_data = HashMap::<u8, TempSkipStats>::new();
for node in self.nodes() {
if let Some(&lvl) = level_map.get(&node.id()) {
let entry = level_data.entry(lvl).or_insert_with(TempSkipStats::default);
entry.node_count += 1;
if node.child_ids().is_empty() {
entry.leaf_count += 1;
}
}
}
let mut result = HashMap::new();
for (lvl, tmp) in level_data {
let stats = TreeLevelSkippingStatsBuilder::default()
.level(lvl)
.total_node_count(tmp.node_count)
.total_leaf_count(tmp.leaf_count)
.build()
.unwrap();
result.insert(lvl, stats);
}
result
}
}
#[cfg(test)]
mod skeleton_level_skipping_measurer_assessment {
use super::*;
#[traced_test]
fn check_level_skipping_linear() {
let n0 = SkeletonNodeBuilder::default()
.id(0u16)
.child_ids(vec![1u16])
.name("root")
.original_key("root")
.build(NodeKind::Dispatch)
.unwrap();
let n1 = SkeletonNodeBuilder::default()
.id(1u16)
.child_ids(vec![2u16])
.name("child")
.original_key("child")
.build(NodeKind::Dispatch)
.unwrap();
let n2 = SkeletonNodeBuilder::default()
.id(2u16)
.name("grandchild")
.original_key("grandchild")
.build(NodeKind::LeafHolder)
.unwrap();
let skel = SkeletonBuilder::default()
.nodes(vec![n0, n1, n2])
.root_id(Some(0u16))
.build()
.unwrap();
let skip_stats = skel.measure_tree_level_skipping();
let lv0 = skip_stats.get(&0).unwrap();
assert_eq!(*lv0.total_node_count(), 1);
assert_eq!(*lv0.total_leaf_count(), 0);
let lv1 = skip_stats.get(&1).unwrap();
assert_eq!(*lv1.total_node_count(), 1);
assert_eq!(*lv1.total_leaf_count(), 0);
let lv2 = skip_stats.get(&2).unwrap();
assert_eq!(*lv2.total_node_count(), 1);
assert_eq!(*lv2.total_leaf_count(), 1);
}
}