Skip to content

Commit c96fa42

Browse files
zzylolclaude
andcommitted
refactor: move AccuracyModel to plan-selection
Only Stage 3 checks estimates against accuracy targets, so the AccuracyModel trait (local_guarantee, satisfies) and DefaultAccuracyModel move to asap-plan-selection. logical-optimizer keeps the analytical estimators and exposes local_guarantee, sketch_guarantee and satisfies; DefaultAccuracyModel delegates to them (Q53). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 207cdd1 commit c96fa42

12 files changed

Lines changed: 199 additions & 180 deletions

File tree

‎crates/frontend-promql/tests/univmon_candidates.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::rc::Rc;
22

3-
use asap_logical_optimizer::accuracy::{AccuracyModel, DefaultAccuracyModel};
3+
use asap_plan_selection::{AccuracyModel, DefaultAccuracyModel};
44
mod support;
55
use asap_types::ir::cse::share_common_sub_dags;
66
use asap_types::ir::properties::ErrorMetric;

‎crates/logical-optimizer/src/accuracy/estimators/cms.rs‎

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,16 @@ mod tests {
4545
use asap_types::ir::schema::{GroupingStrategy, SketchKind};
4646
let c = asap_types::ir::operator::agg_intent::default_cardinality();
4747
let params = default_size_params(SketchAlgorithm::Cms, &c, 0.01, 0.001);
48-
let g = DefaultAccuracyModel
49-
.local_guarantee(
50-
&FieldDataType::Sketch(
51-
SketchKind::new(SketchAlgorithm::Cms, params),
52-
GroupingStrategy::default(),
53-
),
54-
&SketchStatistic::Cardinality,
55-
)
56-
.unwrap();
48+
let g = local_guarantee(
49+
&FieldDataType::Sketch(
50+
SketchKind::new(SketchAlgorithm::Cms, params),
51+
GroupingStrategy::default(),
52+
),
53+
&SketchStatistic::Cardinality,
54+
)
55+
.unwrap();
5756
assert_eq!(g.metric, ErrorMetric::Frequency);
58-
assert!(DefaultAccuracyModel.satisfies(
57+
assert!(satisfies(
5958
&g,
6059
&AccuracyTarget::EpsilonDelta {
6160
epsilon: 0.01,
@@ -96,16 +95,15 @@ mod tests {
9695
},
9796
false => GroupingStrategy::default(),
9897
};
99-
DefaultAccuracyModel
100-
.local_guarantee(
101-
&FieldDataType::Sketch(SketchKind::new(SketchAlgorithm::Cms, params), grouping),
102-
&group_count,
103-
)
104-
.unwrap()
98+
local_guarantee(
99+
&FieldDataType::Sketch(SketchKind::new(SketchAlgorithm::Cms, params), grouping),
100+
&group_count,
101+
)
102+
.unwrap()
105103
};
106-
assert!(DefaultAccuracyModel.satisfies(&guarantee(0.01, 0.01, false), &target));
107-
assert!(!DefaultAccuracyModel.satisfies(&guarantee(0.01, 0.01, true), &target));
108-
assert!(DefaultAccuracyModel.satisfies(&guarantee(0.005, 0.005, true), &target));
104+
assert!(satisfies(&guarantee(0.01, 0.01, false), &target));
105+
assert!(!satisfies(&guarantee(0.01, 0.01, true), &target));
106+
assert!(satisfies(&guarantee(0.005, 0.005, true), &target));
109107
}
110108

111109
#[test]
@@ -116,15 +114,14 @@ mod tests {
116114
depth: 5,
117115
heap_size: 10,
118116
};
119-
let topk_frequency = DefaultAccuracyModel
120-
.local_guarantee(
121-
&FieldDataType::Sketch(
122-
SketchKind::new(SketchAlgorithm::CmsWithHeap, cms_heap),
123-
GroupingStrategy::default(),
124-
),
125-
&SketchStatistic::TopK { k: 10 },
126-
)
127-
.expect("heap sketch still provides per-key frequency intervals");
117+
let topk_frequency = local_guarantee(
118+
&FieldDataType::Sketch(
119+
SketchKind::new(SketchAlgorithm::CmsWithHeap, cms_heap),
120+
GroupingStrategy::default(),
121+
),
122+
&SketchStatistic::TopK { k: 10 },
123+
)
124+
.expect("heap sketch still provides per-key frequency intervals");
128125
assert_eq!(topk_frequency.metric, ErrorMetric::Frequency);
129126
}
130127
}

‎crates/logical-optimizer/src/accuracy/estimators/count_sketch.rs‎

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,19 @@ mod tests {
6060
use asap_types::ir::schema::{GroupingStrategy, SketchKind};
6161
let intent = default_cardinality();
6262
let count_sketch = default_size_params(SketchAlgorithm::CountSketch, &intent, 0.01, 0.01);
63-
let guarantee = DefaultAccuracyModel
64-
.local_guarantee(
65-
&FieldDataType::Sketch(
66-
SketchKind::new(SketchAlgorithm::CountSketch, count_sketch),
67-
GroupingStrategy::default(),
68-
),
69-
&SketchStatistic::PointCount {
70-
key: asap_types::ir::scalar::ColumnRef::SampleValue,
71-
value: None,
72-
},
73-
)
74-
.expect("CountSketch has a parameter-derived L2 guarantee");
63+
let guarantee = local_guarantee(
64+
&FieldDataType::Sketch(
65+
SketchKind::new(SketchAlgorithm::CountSketch, count_sketch),
66+
GroupingStrategy::default(),
67+
),
68+
&SketchStatistic::PointCount {
69+
key: asap_types::ir::scalar::ColumnRef::SampleValue,
70+
value: None,
71+
},
72+
)
73+
.expect("CountSketch has a parameter-derived L2 guarantee");
7574
assert_eq!(guarantee.metric, ErrorMetric::L2Frequency);
76-
assert!(DefaultAccuracyModel.satisfies(
75+
assert!(satisfies(
7776
&guarantee,
7877
&AccuracyTarget::EpsilonDelta {
7978
epsilon: 0.01,

‎crates/logical-optimizer/src/accuracy/estimators/hll.rs‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -235,19 +235,18 @@ mod tests {
235235
use asap_types::ir::schema::{GroupingStrategy, SketchKind};
236236
let c = default_cardinality();
237237
let params = default_size_params(SketchAlgorithm::Hll, &c, 0.01, 0.01);
238-
let g = DefaultAccuracyModel
239-
.local_guarantee(
240-
&FieldDataType::Sketch(
241-
SketchKind::new(SketchAlgorithm::Hll, params),
242-
GroupingStrategy::default(),
243-
),
244-
&SketchStatistic::Cardinality,
245-
)
246-
.unwrap();
238+
let g = local_guarantee(
239+
&FieldDataType::Sketch(
240+
SketchKind::new(SketchAlgorithm::Hll, params),
241+
GroupingStrategy::default(),
242+
),
243+
&SketchStatistic::Cardinality,
244+
)
245+
.unwrap();
247246
assert_eq!(g.metric, ErrorMetric::Cardinality);
248247
assert_eq!(g.failure_probability.evaluate(), None);
249-
assert!(DefaultAccuracyModel.satisfies(&g, &AccuracyTarget::Epsilon(0.01)));
250-
assert!(!DefaultAccuracyModel.satisfies(
248+
assert!(satisfies(&g, &AccuracyTarget::Epsilon(0.01)));
249+
assert!(!satisfies(
251250
&g,
252251
&AccuracyTarget::EpsilonDelta {
253252
epsilon: 0.01,

‎crates/logical-optimizer/src/accuracy/estimators/kll.rs‎

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,18 @@ mod tests {
4747
use asap_types::ir::schema::{GroupingStrategy, SketchKind};
4848
let q = default_quantile(0.99);
4949
let params = default_size_params(SketchAlgorithm::Kll, &q, 0.01, 0.01);
50-
let g = DefaultAccuracyModel
51-
.local_guarantee(
52-
&FieldDataType::Sketch(
53-
SketchKind::new(SketchAlgorithm::Kll, params),
54-
GroupingStrategy::default(),
55-
),
56-
&SketchStatistic::Quantile { q: 0.99 },
57-
)
58-
.unwrap();
50+
let g = local_guarantee(
51+
&FieldDataType::Sketch(
52+
SketchKind::new(SketchAlgorithm::Kll, params),
53+
GroupingStrategy::default(),
54+
),
55+
&SketchStatistic::Quantile { q: 0.99 },
56+
)
57+
.unwrap();
5958
assert_eq!(g.metric, ErrorMetric::Rank);
60-
assert!(DefaultAccuracyModel.satisfies(&g, &AccuracyTarget::Epsilon(0.01)));
59+
assert!(satisfies(&g, &AccuracyTarget::Epsilon(0.01)));
6160
assert_eq!(g.failure_probability.evaluate(), Some(0.01));
62-
assert!(DefaultAccuracyModel.satisfies(
61+
assert!(satisfies(
6362
&g,
6463
&AccuracyTarget::EpsilonDelta {
6564
epsilon: 0.01,

‎crates/logical-optimizer/src/accuracy/estimators/mod.rs‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ pub mod hll;
1111
pub mod kll;
1212
pub mod univmon;
1313

14-
pub(super) fn sketch_guarantee(
14+
/// The guarantee of reading `query` out of a sketch with these committed
15+
/// parameters, built over an exact input; `None` when no error model covers
16+
/// the pair.
17+
pub fn sketch_guarantee(
1518
algorithm: &SketchAlgorithm,
1619
params: &SketchParams,
1720
query: &SketchStatistic,
@@ -55,10 +58,12 @@ fn bounded_guarantee(
5558
}
5659
}
5760

58-
pub(super) fn local_guarantee(
59-
family: &FieldDataType,
60-
query: &SketchStatistic,
61-
) -> Option<ResultGuarantee> {
61+
/// The guarantee of reading `query` out of a summary of family `family` built
62+
/// over an **exact** input — derived from the family's committed parameters by
63+
/// inverting the same sizing formulas
64+
/// [`crate::pass1::realization::default_size_params`] uses. `None` when no
65+
/// error model covers the family (none does for `Sample`/`Wavelet`/`StatModel`).
66+
pub fn local_guarantee(family: &FieldDataType, query: &SketchStatistic) -> Option<ResultGuarantee> {
6267
match family {
6368
FieldDataType::Plain(_) => Some(ResultGuarantee::exact("Plain value")),
6469
FieldDataType::ExactAggregate(kind, _) => {

‎crates/logical-optimizer/src/accuracy/estimators/univmon.rs‎

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ mod tests {
158158
}
159159

160160
fn l2(params: SketchParams) -> Option<ResultGuarantee> {
161-
DefaultAccuracyModel.local_guarantee(&family(params), &SketchStatistic::FrequencyL2)
161+
local_guarantee(&family(params), &SketchStatistic::FrequencyL2)
162162
}
163163

164164
fn shape(params: &SketchParams) -> (u32, u32) {
@@ -191,12 +191,10 @@ mod tests {
191191
key: ColumnRef::SampleValue,
192192
value: None,
193193
};
194-
assert!(DefaultAccuracyModel
195-
.local_guarantee(&family(params.clone()), &total)
196-
.is_some_and(|g| g.is_exact()));
194+
assert!(local_guarantee(&family(params.clone()), &total).is_some_and(|g| g.is_exact()));
197195
let guarantee = l2(params.clone()).expect("L2 is certified");
198196
assert_eq!(guarantee.metric, ErrorMetric::RelativeValue);
199-
assert!(DefaultAccuracyModel.satisfies(
197+
assert!(crate::accuracy::satisfies(
200198
&guarantee,
201199
&AccuracyTarget::EpsilonDelta {
202200
epsilon: 0.01,
@@ -208,9 +206,7 @@ mod tests {
208206
SketchStatistic::FrequencyEntropy,
209207
] {
210208
assert!(
211-
DefaultAccuracyModel
212-
.local_guarantee(&family(params.clone()), &query)
213-
.is_none(),
209+
local_guarantee(&family(params.clone()), &query).is_none(),
214210
"{query:?}"
215211
);
216212
}

0 commit comments

Comments
 (0)