use crate::algebra::Algebra;
use std::time::Duration;
#[derive(Debug, Clone)]
pub struct ExecutionRecord {
pub query_hash: u64,
pub algebra: Algebra,
pub execution_time: Duration,
pub cardinality: usize,
pub memory_usage: usize,
pub optimization_decisions: Vec<OptimizationDecision>,
}
#[derive(Debug, Clone)]
pub struct OptimizationDecision {
pub optimization_type: OptimizationType,
pub before_cost: f64,
pub after_cost: f64,
pub success: bool,
}
#[derive(Debug, Clone)]
pub enum OptimizationType {
JoinReordering,
FilterPushdown,
ProjectionPushdown,
ConstantFolding,
IndexSelection,
MaterializationPoint,
ParallelizationStrategy,
}
#[derive(Debug, Clone)]
pub struct QueryCharacteristics {
pub variable_count: usize,
pub has_object_variables: bool,
pub has_literal_constraints: bool,
pub join_complexity: JoinComplexity,
pub pattern_count: usize,
}
#[derive(Debug, Clone)]
pub enum JoinComplexity {
Simple, Moderate, Complex, }
impl ExecutionRecord {
pub fn new(query_hash: u64, algebra: Algebra) -> Self {
Self {
query_hash,
algebra,
execution_time: Duration::default(),
cardinality: 0,
memory_usage: 0,
optimization_decisions: Vec::new(),
}
}
pub fn add_decision(&mut self, decision: OptimizationDecision) {
self.optimization_decisions.push(decision);
}
pub fn total_benefit(&self) -> f64 {
self.optimization_decisions
.iter()
.map(|d| d.before_cost - d.after_cost)
.sum()
}
}
impl OptimizationDecision {
pub fn new(optimization_type: OptimizationType, before_cost: f64, after_cost: f64) -> Self {
Self {
optimization_type,
before_cost,
after_cost,
success: after_cost < before_cost,
}
}
pub fn benefit(&self) -> f64 {
if self.success {
self.before_cost - self.after_cost
} else {
0.0
}
}
}