crate::ix!();
#[cfg(test)]
mod skeleton_measurement_edge_cases_assessment {
use super::*;
fn make_linear_chain_skeleton(n: u16) -> Skeleton {
let chain_len = if n > 255 { 255 } else { n };
trace!("Constructing a linear chain of length={}", chain_len);
let mut nodes = Vec::with_capacity(chain_len as usize);
for i in 0..chain_len {
let mut builder = SkeletonNodeBuilder::default()
.id(i)
.name(format!("node_{}", i))
.original_key(format!("node_{}", i));
if i < chain_len - 1 {
builder = builder.child_ids(vec![i+1]);
}
let kind = if i < chain_len - 1 {
NodeKind::Dispatch
} else {
NodeKind::LeafHolder
};
let node = builder.build(kind).expect("build node");
nodes.push(node);
}
SkeletonBuilder::default()
.nodes(nodes)
.root_id(Some(0_u16))
.build()
.expect("build skeleton")
}
fn make_uniform_branching_skeleton(node_count: u16, each_child_count: u8) -> Skeleton {
trace!(
"Constructing a skeleton with {} nodes, each having {} children (where possible).",
node_count,
each_child_count
);
let mut nodes = Vec::new();
for i in 0..node_count {
let mut child_ids = Vec::new();
let base_child_id = (i + 1) * 100;
for c in 0..each_child_count {
child_ids.push(base_child_id + c as u16);
}
let k = if child_ids.is_empty() {
NodeKind::LeafHolder
} else {
NodeKind::Dispatch
};
let node = SkeletonNodeBuilder::default()
.id(i)
.child_ids(child_ids)
.name(format!("branchyNode_{}", i))
.original_key(format!("branchyNode_{}", i))
.build(k)
.expect("build node");
nodes.push(node);
}
SkeletonBuilder::default()
.nodes(nodes)
.root_id(Some(0_u16))
.build()
.expect("build skeleton")
}
#[traced_test]
fn depth_saturates_at_255() {
let skel = make_linear_chain_skeleton(300);
let depth = skel.measure_tree_depth();
assert_eq!(depth, 255);
}
#[traced_test]
fn uniform_branching_with_invalid_children() {
let skel = make_uniform_branching_skeleton(10, 5);
let stats = skel.measure_tree_weighted_branching();
assert_eq!(*stats.total_nodes_in_tree(), 10);
assert_eq!(*stats.min_child_count_in_tree(), 5);
assert_eq!(*stats.max_child_count_in_tree(), 5);
assert_eq!(*stats.total_child_count_in_tree(), 50);
assert!((*stats.average_child_count_in_tree() - 5.0).abs() < f32::EPSILON);
}
#[traced_test]
fn all_leaf_scenario_for_level_skipping() {
let mut nodes = Vec::new();
for i in 0..5_u16 {
let node = SkeletonNodeBuilder::default()
.id(i)
.name(format!("leafOnly_{}", i))
.original_key(format!("leafOnly_{}", i))
.build(NodeKind::LeafHolder)
.unwrap();
nodes.push(node);
}
let skel = SkeletonBuilder::default()
.nodes(nodes)
.root_id(Some(0_u16))
.build()
.unwrap();
let stats_map = skel.measure_tree_level_skipping();
let root_level = stats_map.get(&0).unwrap();
assert_eq!(*root_level.total_node_count(), 1);
assert_eq!(*root_level.total_leaf_count(), 1);
}
#[traced_test]
fn no_leaf_scenario_for_level_skipping() {
let n0 = SkeletonNodeBuilder::default()
.id(0u16)
.child_ids(vec![1u16])
.name("node0")
.original_key("node0")
.build(NodeKind::Dispatch)
.unwrap();
let n1 = SkeletonNodeBuilder::default()
.id(1u16)
.child_ids(vec![2u16])
.name("node1")
.original_key("node1")
.build(NodeKind::Dispatch)
.unwrap();
let n2 = SkeletonNodeBuilder::default()
.id(2u16)
.child_ids(vec![99u16])
.name("node2")
.original_key("node2")
.build(NodeKind::Dispatch)
.unwrap();
let skel = SkeletonBuilder::default()
.nodes(vec![n0,n1,n2])
.root_id(Some(0u16))
.build()
.unwrap();
let skip_stats = skel.measure_tree_level_skipping();
assert_eq!(*skip_stats.get(&0).unwrap().total_leaf_count(), 0);
assert_eq!(*skip_stats.get(&1).unwrap().total_leaf_count(), 0);
assert_eq!(*skip_stats.get(&2).unwrap().total_leaf_count(), 0);
}
#[traced_test]
fn large_leaf_count_density() {
let n0 = SkeletonNodeBuilder::default()
.id(0u16)
.leaf_count(65535)
.name("massLeafNode0")
.original_key("massLeafNode0")
.build(NodeKind::LeafHolder)
.unwrap();
let n1 = SkeletonNodeBuilder::default()
.id(1u16)
.leaf_count(65535)
.name("massLeafNode1")
.original_key("massLeafNode1")
.build(NodeKind::LeafHolder)
.unwrap();
let n2 = SkeletonNodeBuilder::default()
.id(2u16)
.leaf_count(65535)
.name("massLeafNode2")
.original_key("massLeafNode2")
.build(NodeKind::LeafHolder)
.unwrap();
let skel = SkeletonBuilder::default()
.nodes(vec![n0, n1, n2])
.root_id(Some(0u16))
.build()
.unwrap();
let dist = skel.measure_tree_density_distribution();
assert_eq!(dist, vec![65535, 65535, 65535]);
}
#[traced_test]
fn random_sub_branch_ordering_is_unknown() {
let nodeA = SkeletonNodeBuilder::default()
.id(0u16)
.child_ids(vec![55u16, 3u16, 999u16, 1u16])
.name("nodeA")
.original_key("nodeA")
.build(NodeKind::Dispatch)
.unwrap();
let nodeB = SkeletonNodeBuilder::default()
.id(55u16)
.name("nodeB")
.original_key("nodeB")
.build(NodeKind::LeafHolder)
.unwrap();
let skel = SkeletonBuilder::default()
.nodes(vec![nodeA, nodeB])
.root_id(Some(0u16))
.build()
.unwrap();
let orderings = skel.measure_tree_sub_branch_orderings();
assert_eq!(orderings.len(), 2);
for ord in orderings {
assert!(matches!(ord, SubBranchOrdering::None));
}
}
}