agentic_evolve_core/optimization/
cache.rs1use std::collections::HashMap;
4
5#[derive(Debug, Clone)]
7pub struct CachedMatch {
8 pub pattern_id: String,
9 pub score: f64,
10 pub timestamp: i64,
11 pub hit_count: u64,
12}
13
14#[derive(Debug)]
16pub struct CacheManager {
17 cache: HashMap<String, Vec<CachedMatch>>,
18 max_entries: usize,
19 ttl_seconds: i64,
20}
21
22impl CacheManager {
23 pub fn new(max_entries: usize, ttl_seconds: i64) -> Self {
24 Self {
25 cache: HashMap::new(),
26 max_entries,
27 ttl_seconds,
28 }
29 }
30
31 pub fn get(&mut self, key: &str) -> Option<&Vec<CachedMatch>> {
32 let now = chrono::Utc::now().timestamp();
33 if let Some(entries) = self.cache.get(key) {
35 if let Some(first) = entries.first() {
36 if now - first.timestamp > self.ttl_seconds {
37 self.cache.remove(key);
38 return None;
39 }
40 }
41 }
42 self.cache.get(key)
43 }
44
45 pub fn put(&mut self, key: &str, matches: Vec<CachedMatch>) {
46 if self.cache.len() >= self.max_entries {
47 self.evict_oldest();
48 }
49 self.cache.insert(key.to_string(), matches);
50 }
51
52 pub fn invalidate(&mut self, key: &str) {
53 self.cache.remove(key);
54 }
55
56 pub fn invalidate_pattern(&mut self, pattern_id: &str) {
57 self.cache
58 .retain(|_, entries| !entries.iter().any(|e| e.pattern_id == pattern_id));
59 }
60
61 pub fn clear(&mut self) {
62 self.cache.clear();
63 }
64
65 pub fn size(&self) -> usize {
66 self.cache.len()
67 }
68
69 pub fn hit_rate(&self) -> f64 {
70 let total_hits: u64 = self
71 .cache
72 .values()
73 .flat_map(|entries| entries.iter())
74 .map(|e| e.hit_count)
75 .sum();
76 let total_entries: u64 = self
77 .cache
78 .values()
79 .map(|entries| entries.len() as u64)
80 .sum();
81 if total_entries == 0 {
82 0.0
83 } else {
84 total_hits as f64 / total_entries as f64
85 }
86 }
87
88 fn evict_oldest(&mut self) {
89 if let Some(oldest_key) = self
90 .cache
91 .iter()
92 .min_by_key(|(_, entries)| entries.first().map(|e| e.timestamp).unwrap_or(i64::MAX))
93 .map(|(k, _)| k.clone())
94 {
95 self.cache.remove(&oldest_key);
96 }
97 }
98}
99
100impl Default for CacheManager {
101 fn default() -> Self {
102 Self::new(1000, 3600) }
104}