unistore_cache/
stats.rs

1//! 【统计信息】- 缓存统计
2//!
3//! 职责:
4//! - 跟踪缓存命中/未命中
5//! - 提供性能指标
6
7use std::sync::atomic::{AtomicU64, Ordering};
8
9/// 缓存统计
10#[derive(Debug, Default)]
11pub struct CacheStats {
12    /// 命中次数
13    hits: AtomicU64,
14    /// 未命中次数
15    misses: AtomicU64,
16    /// 插入次数
17    inserts: AtomicU64,
18    /// 淘汰次数
19    evictions: AtomicU64,
20    /// 过期删除次数
21    expirations: AtomicU64,
22}
23
24impl CacheStats {
25    /// 创建新的统计实例
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    /// 记录命中
31    pub fn record_hit(&self) {
32        self.hits.fetch_add(1, Ordering::Relaxed);
33    }
34
35    /// 记录未命中
36    pub fn record_miss(&self) {
37        self.misses.fetch_add(1, Ordering::Relaxed);
38    }
39
40    /// 记录插入
41    pub fn record_insert(&self) {
42        self.inserts.fetch_add(1, Ordering::Relaxed);
43    }
44
45    /// 记录淘汰
46    pub fn record_eviction(&self) {
47        self.evictions.fetch_add(1, Ordering::Relaxed);
48    }
49
50    /// 记录过期
51    pub fn record_expiration(&self) {
52        self.expirations.fetch_add(1, Ordering::Relaxed);
53    }
54
55    /// 获取命中次数
56    pub fn hits(&self) -> u64 {
57        self.hits.load(Ordering::Relaxed)
58    }
59
60    /// 获取未命中次数
61    pub fn misses(&self) -> u64 {
62        self.misses.load(Ordering::Relaxed)
63    }
64
65    /// 获取插入次数
66    pub fn inserts(&self) -> u64 {
67        self.inserts.load(Ordering::Relaxed)
68    }
69
70    /// 获取淘汰次数
71    pub fn evictions(&self) -> u64 {
72        self.evictions.load(Ordering::Relaxed)
73    }
74
75    /// 获取过期删除次数
76    pub fn expirations(&self) -> u64 {
77        self.expirations.load(Ordering::Relaxed)
78    }
79
80    /// 计算命中率(0.0 - 1.0)
81    pub fn hit_rate(&self) -> f64 {
82        let hits = self.hits();
83        let total = hits + self.misses();
84        if total == 0 {
85            0.0
86        } else {
87            hits as f64 / total as f64
88        }
89    }
90
91    /// 获取总请求数
92    pub fn total_requests(&self) -> u64 {
93        self.hits() + self.misses()
94    }
95
96    /// 重置统计
97    pub fn reset(&self) {
98        self.hits.store(0, Ordering::Relaxed);
99        self.misses.store(0, Ordering::Relaxed);
100        self.inserts.store(0, Ordering::Relaxed);
101        self.evictions.store(0, Ordering::Relaxed);
102        self.expirations.store(0, Ordering::Relaxed);
103    }
104
105    /// 创建快照
106    pub fn snapshot(&self) -> CacheStatsSnapshot {
107        CacheStatsSnapshot {
108            hits: self.hits(),
109            misses: self.misses(),
110            inserts: self.inserts(),
111            evictions: self.evictions(),
112            expirations: self.expirations(),
113        }
114    }
115}
116
117/// 统计快照(不可变)
118#[derive(Debug, Clone)]
119pub struct CacheStatsSnapshot {
120    /// 命中次数
121    pub hits: u64,
122    /// 未命中次数
123    pub misses: u64,
124    /// 插入次数
125    pub inserts: u64,
126    /// 淘汰次数
127    pub evictions: u64,
128    /// 过期删除次数
129    pub expirations: u64,
130}
131
132impl CacheStatsSnapshot {
133    /// 计算命中率
134    pub fn hit_rate(&self) -> f64 {
135        let total = self.hits + self.misses;
136        if total == 0 {
137            0.0
138        } else {
139            self.hits as f64 / total as f64
140        }
141    }
142
143    /// 获取总请求数
144    pub fn total_requests(&self) -> u64 {
145        self.hits + self.misses
146    }
147}
148
149impl std::fmt::Display for CacheStatsSnapshot {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        write!(
152            f,
153            "CacheStats {{ hits: {}, misses: {}, hit_rate: {:.2}%, inserts: {}, evictions: {}, expirations: {} }}",
154            self.hits,
155            self.misses,
156            self.hit_rate() * 100.0,
157            self.inserts,
158            self.evictions,
159            self.expirations
160        )
161    }
162}