santh_bufpool/stats.rs
1use std::sync::atomic::{AtomicUsize, Ordering};
2
3/// Pool statistics for observability.
4///
5/// All counters use relaxed atomics and are safe to read from any thread.
6///
7/// # Example
8///
9/// ```rust
10/// use santh_bufpool::{BufferPool, PoolConfig};
11///
12/// let pool = BufferPool::new(PoolConfig::default());
13/// let buf = pool.checkout(64).unwrap();
14/// let stats = pool.stats().snapshot();
15/// assert_eq!(stats.checked_out, 1);
16/// drop(buf);
17/// ```
18#[derive(Debug, Default)]
19pub struct PoolStats {
20 /// Number of successful checkouts from the pool (reuse).
21 pub hits: AtomicUsize,
22 /// Number of fallback allocations (pool exhausted).
23 pub misses: AtomicUsize,
24 /// Number of buffers currently checked out.
25 pub checked_out: AtomicUsize,
26 /// Peak simultaneous checkouts observed.
27 pub peak_checked_out: AtomicUsize,
28 /// Total bytes currently checked out (sum of requested sizes).
29 pub bytes_checked_out: AtomicUsize,
30 /// Peak bytes checked out simultaneously.
31 pub peak_bytes_checked_out: AtomicUsize,
32}
33
34impl PoolStats {
35 /// Snapshot the current stats.
36 ///
37 /// # Example
38 ///
39 /// ```rust
40 /// use santh_bufpool::{BufferPool, PoolConfig};
41 ///
42 /// let pool = BufferPool::new(PoolConfig::default());
43 /// let snapshot = pool.stats().snapshot();
44 /// assert_eq!(snapshot.hits, 0);
45 /// ```
46 #[must_use]
47 pub fn snapshot(&self) -> PoolStatsSnapshot {
48 PoolStatsSnapshot {
49 hits: self.hits.load(Ordering::Relaxed),
50 misses: self.misses.load(Ordering::Relaxed),
51 checked_out: self.checked_out.load(Ordering::Relaxed),
52 peak_checked_out: self.peak_checked_out.load(Ordering::Relaxed),
53 bytes_checked_out: self.bytes_checked_out.load(Ordering::Relaxed),
54 peak_bytes_checked_out: self.peak_bytes_checked_out.load(Ordering::Relaxed),
55 }
56 }
57}
58
59/// Immutable snapshot of pool statistics.
60///
61/// # Example
62///
63/// ```rust
64/// use santh_bufpool::{BufferPool, PoolConfig, PoolStatsSnapshot};
65///
66/// let pool = BufferPool::new(PoolConfig::default());
67/// let snap = pool.stats().snapshot();
68/// assert_eq!(snap.checked_out, 0);
69/// ```
70#[derive(Debug, Clone, Copy)]
71pub struct PoolStatsSnapshot {
72 /// Number of pool hits (reuse).
73 pub hits: usize,
74 /// Number of pool misses (fallback alloc).
75 pub misses: usize,
76 /// Currently checked out.
77 pub checked_out: usize,
78 /// Peak simultaneous checkouts.
79 pub peak_checked_out: usize,
80 /// Total bytes currently checked out.
81 pub bytes_checked_out: usize,
82 /// Peak bytes checked out simultaneously.
83 pub peak_bytes_checked_out: usize,
84}