oxirs_arq/optimizer/
execution_tracking.rs1use crate::algebra::Algebra;
6use std::time::Duration;
7
8#[derive(Debug, Clone)]
10pub struct ExecutionRecord {
11 pub query_hash: u64,
12 pub algebra: Algebra,
13 pub execution_time: Duration,
14 pub cardinality: usize,
15 pub memory_usage: usize,
16 pub optimization_decisions: Vec<OptimizationDecision>,
17}
18
19#[derive(Debug, Clone)]
21pub struct OptimizationDecision {
22 pub optimization_type: OptimizationType,
23 pub before_cost: f64,
24 pub after_cost: f64,
25 pub success: bool,
26}
27
28#[derive(Debug, Clone)]
30pub enum OptimizationType {
31 JoinReordering,
32 FilterPushdown,
33 ProjectionPushdown,
34 ConstantFolding,
35 IndexSelection,
36 MaterializationPoint,
37 ParallelizationStrategy,
38}
39
40#[derive(Debug, Clone)]
42pub struct QueryCharacteristics {
43 pub variable_count: usize,
44 pub has_object_variables: bool,
45 pub has_literal_constraints: bool,
46 pub join_complexity: JoinComplexity,
47 pub pattern_count: usize,
48}
49
50#[derive(Debug, Clone)]
52pub enum JoinComplexity {
53 Simple, Moderate, Complex, }
57
58impl ExecutionRecord {
59 pub fn new(query_hash: u64, algebra: Algebra) -> Self {
61 Self {
62 query_hash,
63 algebra,
64 execution_time: Duration::default(),
65 cardinality: 0,
66 memory_usage: 0,
67 optimization_decisions: Vec::new(),
68 }
69 }
70
71 pub fn add_decision(&mut self, decision: OptimizationDecision) {
73 self.optimization_decisions.push(decision);
74 }
75
76 pub fn total_benefit(&self) -> f64 {
78 self.optimization_decisions
79 .iter()
80 .map(|d| d.before_cost - d.after_cost)
81 .sum()
82 }
83}
84
85impl OptimizationDecision {
86 pub fn new(optimization_type: OptimizationType, before_cost: f64, after_cost: f64) -> Self {
88 Self {
89 optimization_type,
90 before_cost,
91 after_cost,
92 success: after_cost < before_cost,
93 }
94 }
95
96 pub fn benefit(&self) -> f64 {
98 if self.success {
99 self.before_cost - self.after_cost
100 } else {
101 0.0
102 }
103 }
104}