statsig_client/
cache_metrics.rs

1//! Cache metrics and monitoring for the Statsig client
2//!
3//! This module provides metrics collection for cache performance monitoring.
4
5use std::sync::atomic::{AtomicU64, Ordering};
6
7/// Cache performance metrics
8#[derive(Debug, Default)]
9pub struct CacheMetrics {
10    /// Number of cache hits
11    hits: AtomicU64,
12    /// Number of cache misses
13    misses: AtomicU64,
14    /// Number of items inserted into cache
15    inserts: AtomicU64,
16    /// Number of items evicted from cache
17    evictions: AtomicU64,
18}
19
20impl CacheMetrics {
21    /// Create new cache metrics
22    pub fn new() -> Self {
23        Self::default()
24    }
25
26    /// Record a cache hit
27    pub fn record_hit(&self) {
28        self.hits.fetch_add(1, Ordering::Relaxed);
29    }
30
31    /// Record a cache miss
32    pub fn record_miss(&self) {
33        self.misses.fetch_add(1, Ordering::Relaxed);
34    }
35
36    /// Record a cache insertion
37    pub fn record_insert(&self) {
38        self.inserts.fetch_add(1, Ordering::Relaxed);
39    }
40
41    /// Record a cache eviction
42    pub fn record_eviction(&self) {
43        self.evictions.fetch_add(1, Ordering::Relaxed);
44    }
45
46    /// Get the total number of cache hits
47    pub fn hits(&self) -> u64 {
48        self.hits.load(Ordering::Relaxed)
49    }
50
51    /// Get the total number of cache misses
52    pub fn misses(&self) -> u64 {
53        self.misses.load(Ordering::Relaxed)
54    }
55
56    /// Get the total number of cache inserts
57    pub fn inserts(&self) -> u64 {
58        self.inserts.load(Ordering::Relaxed)
59    }
60
61    /// Get the total number of cache evictions
62    pub fn evictions(&self) -> u64 {
63        self.evictions.load(Ordering::Relaxed)
64    }
65
66    /// Get the total number of cache requests (hits + misses)
67    pub fn total_requests(&self) -> u64 {
68        self.hits() + self.misses()
69    }
70
71    /// Get the cache hit ratio as a percentage (0.0 to 100.0)
72    pub fn hit_ratio(&self) -> f64 {
73        let total = self.total_requests();
74        if total == 0 {
75            0.0
76        } else {
77            (self.hits() as f64 / total as f64) * 100.0
78        }
79    }
80
81    /// Reset all metrics to zero
82    pub fn reset(&self) {
83        self.hits.store(0, Ordering::Relaxed);
84        self.misses.store(0, Ordering::Relaxed);
85        self.inserts.store(0, Ordering::Relaxed);
86        self.evictions.store(0, Ordering::Relaxed);
87    }
88
89    /// Get a summary of cache metrics
90    pub fn summary(&self) -> CacheMetricsSummary {
91        CacheMetricsSummary {
92            hits: self.hits(),
93            misses: self.misses(),
94            inserts: self.inserts(),
95            evictions: self.evictions(),
96            total_requests: self.total_requests(),
97            hit_ratio: self.hit_ratio(),
98        }
99    }
100}
101
102/// A summary of cache metrics for reporting
103#[derive(Debug, Clone)]
104pub struct CacheMetricsSummary {
105    pub hits: u64,
106    pub misses: u64,
107    pub inserts: u64,
108    pub evictions: u64,
109    pub total_requests: u64,
110    pub hit_ratio: f64,
111}
112
113impl std::fmt::Display for CacheMetricsSummary {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        write!(
116            f,
117            "Cache Metrics: {} hits, {} misses, {:.2}% hit ratio, {} inserts, {} evictions",
118            self.hits, self.misses, self.hit_ratio, self.inserts, self.evictions
119        )
120    }
121}