agentic_forge_core/cache/
metrics.rs1use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
4
5pub struct CacheMetrics {
6 hit_count: AtomicU64,
7 miss_count: AtomicU64,
8 eviction_count: AtomicU64,
9 current_size: AtomicUsize,
10}
11
12impl CacheMetrics {
13 pub fn new() -> Self {
14 Self {
15 hit_count: AtomicU64::new(0),
16 miss_count: AtomicU64::new(0),
17 eviction_count: AtomicU64::new(0),
18 current_size: AtomicUsize::new(0),
19 }
20 }
21
22 pub fn record_hit(&self) {
23 self.hit_count.fetch_add(1, Ordering::Relaxed);
24 }
25
26 pub fn record_miss(&self) {
27 self.miss_count.fetch_add(1, Ordering::Relaxed);
28 }
29
30 pub fn record_eviction(&self) {
31 self.eviction_count.fetch_add(1, Ordering::Relaxed);
32 }
33
34 pub fn set_size(&self, size: usize) {
35 self.current_size.store(size, Ordering::Relaxed);
36 }
37
38 pub fn hits(&self) -> u64 {
39 self.hit_count.load(Ordering::Relaxed)
40 }
41
42 pub fn misses(&self) -> u64 {
43 self.miss_count.load(Ordering::Relaxed)
44 }
45
46 pub fn evictions(&self) -> u64 {
47 self.eviction_count.load(Ordering::Relaxed)
48 }
49
50 pub fn size(&self) -> usize {
51 self.current_size.load(Ordering::Relaxed)
52 }
53
54 pub fn total_requests(&self) -> u64 {
55 self.hits() + self.misses()
56 }
57
58 pub fn hit_rate(&self) -> f64 {
59 let total = self.total_requests();
60 if total == 0 {
61 return 0.0;
62 }
63 self.hits() as f64 / total as f64
64 }
65
66 pub fn reset(&self) {
67 self.hit_count.store(0, Ordering::Relaxed);
68 self.miss_count.store(0, Ordering::Relaxed);
69 self.eviction_count.store(0, Ordering::Relaxed);
70 }
71}
72
73impl Default for CacheMetrics {
74 fn default() -> Self {
75 Self::new()
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_metrics_initial() {
85 let m = CacheMetrics::new();
86 assert_eq!(m.hits(), 0);
87 assert_eq!(m.misses(), 0);
88 assert_eq!(m.hit_rate(), 0.0);
89 }
90
91 #[test]
92 fn test_metrics_hit_rate() {
93 let m = CacheMetrics::new();
94 m.record_hit();
95 m.record_hit();
96 m.record_miss();
97 assert!((m.hit_rate() - 0.6667).abs() < 0.01);
98 }
99
100 #[test]
101 fn test_metrics_reset() {
102 let m = CacheMetrics::new();
103 m.record_hit();
104 m.record_miss();
105 m.reset();
106 assert_eq!(m.total_requests(), 0);
107 }
108
109 #[test]
110 fn test_metrics_evictions() {
111 let m = CacheMetrics::new();
112 m.record_eviction();
113 m.record_eviction();
114 assert_eq!(m.evictions(), 2);
115 }
116}