capability_grower_configuration_comparison/
compare_depth_limits.rs1crate::ix!();
3
4pub trait CompareDepthLimits {
5 fn compare_depth_limits(&self, other: &GrowerTreeConfiguration) -> CompareOutcome;
6}
7
8impl CompareDepthLimits for GrowerTreeConfiguration {
9 fn compare_depth_limits(&self, other: &GrowerTreeConfiguration) -> CompareOutcome {
10 let mut score = 1.0;
11
12 match (self.aggregator_depth_limit(), other.aggregator_depth_limit()) {
14 (None, None) => {},
15 (None, Some(_)) | (Some(_), None) => {
16 score *= 0.8;
17 },
18 (Some(a), Some(b)) => {
19 let diff = (*a as i32 - *b as i32).abs();
20 if diff > 10 {
22 return CompareOutcome::Incompatible;
23 } else if diff > 0 {
24 score *= 0.8;
25 }
26 }
27 }
28
29 match (self.dispatch_depth_limit(), other.dispatch_depth_limit()) {
31 (None, None) => {},
32 (None, Some(_)) | (Some(_), None) => {
33 score *= 0.8;
34 },
35 (Some(a), Some(b)) => {
36 let diff = (*a as i32 - *b as i32).abs();
37 if diff > 10 {
38 return CompareOutcome::Incompatible;
39 } else if diff > 0 {
40 score *= 0.8;
41 }
42 }
43 }
44
45 match (self.leaf_min_depth(), other.leaf_min_depth()) {
47 (None, None) => {},
48 (None, Some(_)) | (Some(_), None) => {
49 score *= 0.8;
50 },
51 (Some(a), Some(b)) => {
52 let diff = (*a as i32 - *b as i32).abs();
53 if diff > 10 {
54 return CompareOutcome::Incompatible;
55 } else if diff > 0 {
56 score *= 0.8;
57 }
58 }
59 }
60
61 if score < 0.2 {
62 CompareOutcome::Incompatible
63 } else if score < 1.0 {
64 CompareOutcome::Partial(score)
65 } else {
66 CompareOutcome::Exact
67 }
68 }
69}
70
71#[cfg(test)]
72mod compare_depth_limits_tests {
73 use super::*;
74
75 #[traced_test]
76 fn all_none_exact() {
77 let a = GrowerTreeConfiguration::default();
78 let b = a.clone();
79 assert_eq!(a.compare_depth_limits(&b), CompareOutcome::Exact);
80 }
81
82 #[traced_test]
83 fn aggregator_diff_small_partial() {
84 let a = GrowerTreeConfiguration::default()
85 .to_builder().aggregator_depth_limit(Some(5)).build().unwrap();
86 let b = a.to_builder().aggregator_depth_limit(Some(6)).build().unwrap();
87 match a.compare_depth_limits(&b) {
88 CompareOutcome::Partial(sc) => assert!(sc < 1.0),
89 other => panic!("expected partial, got {:?}", other),
90 }
91 }
92
93 #[traced_test]
94 fn aggregator_diff_large_incompatible() {
95 let a = GrowerTreeConfiguration::default()
97 .to_builder().aggregator_depth_limit(Some(2)).build().unwrap();
98 let b = a.to_builder().aggregator_depth_limit(Some(13)).build().unwrap();
99 assert_eq!(a.compare_depth_limits(&b), CompareOutcome::Incompatible);
100 }
101
102 #[traced_test]
103 fn dispatch_leaf_none_agg_partial() {
104 let a = GrowerTreeConfiguration::default()
105 .to_builder()
106 .aggregator_depth_limit(Some(3))
107 .dispatch_depth_limit(None)
108 .leaf_min_depth(None)
109 .build().unwrap();
110 let b = a.to_builder()
111 .aggregator_depth_limit(None)
112 .build().unwrap();
113 match a.compare_depth_limits(&b) {
114 CompareOutcome::Partial(sc) => assert!(sc < 1.0),
115 other => panic!("expected partial, got {:?}", other),
116 }
117 }
118
119 #[traced_test]
120 fn all_same_exact() {
121 let a = GrowerTreeConfiguration::default()
122 .to_builder()
123 .aggregator_depth_limit(Some(3))
124 .dispatch_depth_limit(Some(5))
125 .leaf_min_depth(Some(2))
126 .build().unwrap();
127 let b = a.clone();
128 assert_eq!(a.compare_depth_limits(&b), CompareOutcome::Exact);
129 }
130}