linkrs_query/optimizer/
context.rs1use std::sync::Arc;
7
8use crate::optimizer::analysis::{BatchPlanAnalysis, ExpressionAnalysis, ReferenceCountAnalysis};
9use crate::optimizer::cost::{CostCalculator, CostModelConfig, SelectivityEstimator};
10use crate::optimizer::stats::StatisticsManager;
11use linkrs_core::types::expr::expression_context::ExpressionAnalysisContext;
12
13#[derive(Clone)]
18pub struct OptimizationContext {
19 stats_manager: Arc<StatisticsManager>,
21 cost_calculator: Arc<CostCalculator>,
23 selectivity_estimator: Arc<SelectivityEstimator>,
25 cost_config: CostModelConfig,
27 expression_context: Arc<ExpressionAnalysisContext>,
29 reference_count_analysis: Option<ReferenceCountAnalysis>,
31 expression_analysis: Option<ExpressionAnalysis>,
33 batch_plan_analysis: Option<BatchPlanAnalysis>,
35}
36
37impl OptimizationContext {
38 pub fn new(
40 stats_manager: Arc<StatisticsManager>,
41 cost_calculator: Arc<CostCalculator>,
42 selectivity_estimator: Arc<SelectivityEstimator>,
43 cost_config: CostModelConfig,
44 expression_context: Arc<ExpressionAnalysisContext>,
45 ) -> Self {
46 Self {
47 stats_manager,
48 cost_calculator,
49 selectivity_estimator,
50 cost_config,
51 expression_context,
52 reference_count_analysis: None,
53 expression_analysis: None,
54 batch_plan_analysis: None,
55 }
56 }
57
58 pub fn stats_manager(&self) -> &Arc<StatisticsManager> {
60 &self.stats_manager
61 }
62
63 pub fn cost_calculator(&self) -> &Arc<CostCalculator> {
65 &self.cost_calculator
66 }
67
68 pub fn selectivity_estimator(&self) -> &Arc<SelectivityEstimator> {
70 &self.selectivity_estimator
71 }
72
73 pub fn cost_config(&self) -> &CostModelConfig {
75 &self.cost_config
76 }
77
78 pub fn expression_context(&self) -> &Arc<ExpressionAnalysisContext> {
80 &self.expression_context
81 }
82
83 pub fn set_reference_count_analysis(&mut self, analysis: ReferenceCountAnalysis) {
85 self.reference_count_analysis = Some(analysis);
86 }
87
88 pub fn reference_count_analysis(&self) -> Option<&ReferenceCountAnalysis> {
90 self.reference_count_analysis.as_ref()
91 }
92
93 pub fn set_expression_analysis(&mut self, analysis: ExpressionAnalysis) {
95 self.expression_analysis = Some(analysis);
96 }
97
98 pub fn expression_analysis(&self) -> Option<&ExpressionAnalysis> {
100 self.expression_analysis.as_ref()
101 }
102
103 pub fn set_batch_plan_analysis(&mut self, analysis: BatchPlanAnalysis) {
105 self.batch_plan_analysis = Some(analysis);
106 }
107
108 pub fn batch_plan_analysis(&self) -> Option<&BatchPlanAnalysis> {
110 self.batch_plan_analysis.as_ref()
111 }
112
113 pub fn clear_cache(&mut self) {
115 self.reference_count_analysis = None;
116 self.expression_analysis = None;
117 self.batch_plan_analysis = None;
118 }
119}
120
121use crate::optimizer::OptimizerEngine;
122
123impl From<&OptimizerEngine> for OptimizationContext {
124 fn from(engine: &OptimizerEngine) -> Self {
125 Self::new(
126 engine.stats_manager().clone(),
127 engine.cost_calculator().clone(),
128 engine.selectivity_estimator().clone(),
129 *engine.cost_config(),
130 engine.expression_context().clone(),
131 )
132 }
133}
134
135impl From<&Arc<OptimizerEngine>> for OptimizationContext {
136 fn from(engine: &Arc<OptimizerEngine>) -> Self {
137 Self::from(engine.as_ref())
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn test_optimization_context_creation() {
147 let stats_manager = Arc::new(StatisticsManager::new());
148 let cost_config = CostModelConfig::default();
149 let cost_calculator = Arc::new(CostCalculator::with_config(
150 stats_manager.clone(),
151 cost_config,
152 ));
153 let selectivity_estimator = Arc::new(SelectivityEstimator::new(stats_manager.clone()));
154 let expression_context = Arc::new(ExpressionAnalysisContext::new());
155
156 let ctx = OptimizationContext::new(
157 stats_manager,
158 cost_calculator,
159 selectivity_estimator,
160 cost_config,
161 expression_context,
162 );
163
164 assert!(ctx.reference_count_analysis().is_none());
165 assert!(ctx.expression_analysis().is_none());
166 }
167
168 #[test]
169 fn test_optimization_context_cache() {
170 let stats_manager = Arc::new(StatisticsManager::new());
171 let cost_config = CostModelConfig::default();
172 let cost_calculator = Arc::new(CostCalculator::with_config(
173 stats_manager.clone(),
174 cost_config,
175 ));
176 let selectivity_estimator = Arc::new(SelectivityEstimator::new(stats_manager.clone()));
177 let expression_context = Arc::new(ExpressionAnalysisContext::new());
178
179 let mut ctx = OptimizationContext::new(
180 stats_manager,
181 cost_calculator,
182 selectivity_estimator,
183 cost_config,
184 expression_context,
185 );
186
187 let ref_analysis = ReferenceCountAnalysis::new();
188 ctx.set_reference_count_analysis(ref_analysis.clone());
189 assert!(ctx.reference_count_analysis().is_some());
190
191 let expr_analysis = ExpressionAnalysis::default();
192 ctx.set_expression_analysis(expr_analysis.clone());
193 assert!(ctx.expression_analysis().is_some());
194
195 ctx.clear_cache();
196 assert!(ctx.reference_count_analysis().is_none());
197 assert!(ctx.expression_analysis().is_none());
198 }
199}