linkrs_query/cache/plan_cache/
entry.rs1use crate::cache::config::CachePriority;
2use crate::cache::plan_cache::key::ParamPosition;
3use crate::executor::streaming::plan::PhysicalPlan;
4use std::sync::Arc;
5use std::time::{Duration, Instant};
6
7#[derive(Debug, Clone)]
13pub struct CachedPlan {
14 pub query_template: String,
16 pub plan: Arc<PhysicalPlan>,
18 pub param_positions: Vec<ParamPosition>,
20 pub created_at: Instant,
22 pub last_accessed: Instant,
24 pub access_count: u64,
26 pub avg_execution_time_ms: f64,
28 pub execution_count: u64,
30 pub priority: CachePriority,
32 pub complexity_score: u32,
34 pub estimated_compute_cost: u64,
36 pub current_ttl: Duration,
38 pub dependent_tables: Vec<String>,
40 pub is_dml: bool,
42 pub is_transaction: bool,
44}
45
46impl CachedPlan {
47 pub fn estimate_memory(&self) -> usize {
49 let mut total = 0;
50
51 total += std::mem::size_of::<String>();
52 total += self.query_template.capacity();
53
54 total += std::mem::size_of::<Vec<ParamPosition>>();
55 for pos in &self.param_positions {
56 total += std::mem::size_of::<ParamPosition>();
57 if let Some(ref name) = pos.name {
58 total += std::mem::size_of::<String>();
59 total += name.capacity();
60 }
61 }
62
63 total += self.estimate_plan_memory(&self.plan);
64
65 total += std::mem::size_of::<Instant>() * 2;
66 total += std::mem::size_of::<u64>() * 3;
67 total += std::mem::size_of::<f64>() * 2;
68 total += std::mem::size_of::<CachePriority>();
69 total += std::mem::size_of::<u32>();
70 total += std::mem::size_of::<Duration>();
71
72 total += std::mem::size_of::<Vec<String>>();
73 for table in &self.dependent_tables {
74 total += std::mem::size_of::<String>();
75 total += table.capacity();
76 }
77
78 total
79 }
80
81 fn estimate_plan_memory(&self, plan: &PhysicalPlan) -> usize {
85 let base_size = std::mem::size_of::<PhysicalPlan>();
86 let op_count = plan.operator_count();
87 let fragment_count = plan.fragment_count();
88 let per_op_estimate = 256; base_size + (op_count * per_op_estimate) + (fragment_count * 64)
91 }
92
93 pub fn value_score(&self) -> f64 {
95 let frequency_score = self.access_count as f64 * 0.4;
96 let cost_score = (self.estimated_compute_cost as f64 / 1000.0) * 0.3;
97 let priority_score = (self.priority as i32 as f64) * 0.2;
98 let size_penalty = (self.query_template.len() as f64 / 1024.0) * 0.1;
99
100 frequency_score + cost_score + priority_score - size_penalty
101 }
102}