crate::ix!();
pub trait CompareDensity {
fn compare_density(&self, other: &GrowerTreeConfiguration) -> CompareOutcome;
}
impl CompareDensity for GrowerTreeConfiguration {
fn compare_density(&self, other: &GrowerTreeConfiguration) -> CompareOutcome {
let d1 = *self.density();
let d2 = *other.density();
if d1 == d2 {
CompareOutcome::Exact
} else {
let diff = (d1 as i32 - d2 as i32).abs();
if diff > 10 {
CompareOutcome::Incompatible
} else {
let penalty = 0.05 * diff as f32;
let score = (1.0 - penalty).max(0.0);
CompareOutcome::Partial(score)
}
}
}
}
#[cfg(test)]
mod compare_density_tests {
use super::*;
#[traced_test]
fn same_exact() {
let a = GrowerTreeConfiguration::base_config(5, 3, 2);
let b = GrowerTreeConfiguration::base_config(5, 1, 2);
assert_eq!(a.compare_density(&b), CompareOutcome::Exact);
}
#[traced_test]
fn difference_small_partial() {
let a = GrowerTreeConfiguration::base_config(5, 3, 2);
let mut b = a.clone();
b = b.to_builder().density(3).build().unwrap(); let out = a.compare_density(&b);
match out {
CompareOutcome::Partial(_) => {},
other => panic!("expected partial, got {:?}", other),
}
}
#[traced_test]
fn difference_large_incompatible() {
let a = GrowerTreeConfiguration::base_config(5, 3, 2);
let mut b = a.clone();
b = b.to_builder().density(15).build().unwrap();
assert_eq!(a.compare_density(&b), CompareOutcome::Incompatible);
}
}