use crate::cache::config::CachePriority;
use crate::cache::plan_cache::key::ParamPosition;
use crate::executor::streaming::plan::PhysicalPlan;
use std::sync::Arc;
use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct CachedPlan {
pub query_template: String,
pub plan: Arc<PhysicalPlan>,
pub param_positions: Vec<ParamPosition>,
pub created_at: Instant,
pub last_accessed: Instant,
pub access_count: u64,
pub avg_execution_time_ms: f64,
pub execution_count: u64,
pub priority: CachePriority,
pub complexity_score: u32,
pub estimated_compute_cost: u64,
pub current_ttl: Duration,
pub dependent_tables: Vec<String>,
pub is_dml: bool,
pub is_transaction: bool,
}
impl CachedPlan {
pub fn estimate_memory(&self) -> usize {
let mut total = 0;
total += std::mem::size_of::<String>();
total += self.query_template.capacity();
total += std::mem::size_of::<Vec<ParamPosition>>();
for pos in &self.param_positions {
total += std::mem::size_of::<ParamPosition>();
if let Some(ref name) = pos.name {
total += std::mem::size_of::<String>();
total += name.capacity();
}
}
total += self.estimate_plan_memory(&self.plan);
total += std::mem::size_of::<Instant>() * 2;
total += std::mem::size_of::<u64>() * 3;
total += std::mem::size_of::<f64>() * 2;
total += std::mem::size_of::<CachePriority>();
total += std::mem::size_of::<u32>();
total += std::mem::size_of::<Duration>();
total += std::mem::size_of::<Vec<String>>();
for table in &self.dependent_tables {
total += std::mem::size_of::<String>();
total += table.capacity();
}
total
}
fn estimate_plan_memory(&self, plan: &PhysicalPlan) -> usize {
let base_size = std::mem::size_of::<PhysicalPlan>();
let op_count = plan.operator_count();
let fragment_count = plan.fragment_count();
let per_op_estimate = 256;
base_size + (op_count * per_op_estimate) + (fragment_count * 64)
}
pub fn value_score(&self) -> f64 {
let frequency_score = self.access_count as f64 * 0.4;
let cost_score = (self.estimated_compute_cost as f64 / 1000.0) * 0.3;
let priority_score = (self.priority as i32 as f64) * 0.2;
let size_penalty = (self.query_template.len() as f64 / 1024.0) * 0.1;
frequency_score + cost_score + priority_score - size_penalty
}
}