use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
pub enum CachePriority {
Low = 0,
#[default]
Normal = 1,
High = 2,
Critical = 3,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TtlConfig {
pub base_ttl_seconds: u64,
pub adaptive: bool,
pub min_ttl_seconds: u64,
pub max_ttl_seconds: u64,
}
impl Default for TtlConfig {
fn default() -> Self {
Self {
base_ttl_seconds: 3600,
adaptive: true,
min_ttl_seconds: 300,
max_ttl_seconds: 86400,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PriorityConfig {
pub enable_priority: bool,
pub track_execution_time: bool,
}
impl Default for PriorityConfig {
fn default() -> Self {
Self {
enable_priority: true,
track_execution_time: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlanCacheConfig {
pub max_entries: usize,
pub memory_budget: usize,
pub max_weight: Option<u64>,
pub enable_parameterized: bool,
pub ttl_config: TtlConfig,
pub priority_config: PriorityConfig,
}
impl Default for PlanCacheConfig {
fn default() -> Self {
Self {
max_entries: 1000,
memory_budget: 50 * 1024 * 1024,
max_weight: None,
enable_parameterized: true,
ttl_config: TtlConfig::default(),
priority_config: PriorityConfig::default(),
}
}
}
impl PlanCacheConfig {
pub fn minimal() -> Self {
Self {
max_entries: 200,
memory_budget: 10 * 1024 * 1024,
max_weight: None,
enable_parameterized: true,
ttl_config: TtlConfig {
base_ttl_seconds: 1800,
adaptive: true,
min_ttl_seconds: 60,
max_ttl_seconds: 3600,
},
priority_config: PriorityConfig::default(),
}
}
pub fn high_performance() -> Self {
Self {
max_entries: 5000,
memory_budget: 200 * 1024 * 1024,
max_weight: None,
enable_parameterized: true,
ttl_config: TtlConfig {
base_ttl_seconds: 7200,
adaptive: true,
min_ttl_seconds: 600,
max_ttl_seconds: 86400,
},
priority_config: PriorityConfig::default(),
}
}
pub fn effective_max_weight(&self) -> u64 {
self.max_weight.unwrap_or(self.memory_budget as u64)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CteCacheConfig {
pub max_size: usize,
pub max_entries: Option<usize>,
pub max_entry_size: usize,
pub min_row_count: u64,
pub max_row_count: u64,
pub entry_ttl_seconds: u64,
pub enabled: bool,
pub adaptive: bool,
pub enable_priority: bool,
}
impl Default for CteCacheConfig {
fn default() -> Self {
Self {
max_size: 64 * 1024 * 1024,
max_entries: Some(10000),
max_entry_size: 10 * 1024 * 1024,
min_row_count: 100,
max_row_count: 100_000,
entry_ttl_seconds: 3600,
enabled: true,
adaptive: true,
enable_priority: true,
}
}
}
impl CteCacheConfig {
pub fn low_memory() -> Self {
Self {
max_size: 16 * 1024 * 1024,
max_entries: Some(5000),
max_entry_size: 5 * 1024 * 1024,
min_row_count: 50,
max_row_count: 50_000,
entry_ttl_seconds: 1800,
enabled: true,
adaptive: true,
enable_priority: true,
}
}
pub fn high_memory() -> Self {
Self {
max_size: 256 * 1024 * 1024,
max_entries: Some(20000),
max_entry_size: 50 * 1024 * 1024,
min_row_count: 100,
max_row_count: 500_000,
entry_ttl_seconds: 7200,
enabled: true,
adaptive: true,
enable_priority: true,
}
}
pub fn disabled() -> Self {
Self {
enabled: false,
..Default::default()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ttl_config_default() {
let config = TtlConfig::default();
assert_eq!(config.base_ttl_seconds, 3600);
assert!(config.adaptive);
}
#[test]
fn test_plan_cache_config_default() {
let config = PlanCacheConfig::default();
assert_eq!(config.max_entries, 1000);
assert_eq!(config.memory_budget, 50 * 1024 * 1024);
}
#[test]
fn test_cte_cache_config_default() {
let config = CteCacheConfig::default();
assert_eq!(config.max_size, 64 * 1024 * 1024);
assert!(config.enabled);
}
}