mod collector;
mod reporter;
pub use collector::StatisticsCollector;
pub use reporter::StatisticsReporter;
use core::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PoolStatistics {
pub total_allocations: usize,
pub total_deallocations: usize,
pub current_usage: usize,
pub peak_usage: usize,
pub capacity: usize,
pub growth_count: usize,
pub allocation_failures: usize,
}
impl PoolStatistics {
pub fn new(capacity: usize) -> Self {
Self {
total_allocations: 0,
total_deallocations: 0,
current_usage: 0,
peak_usage: 0,
capacity,
growth_count: 0,
allocation_failures: 0,
}
}
#[inline]
pub fn utilization_rate(&self) -> f64 {
if self.capacity == 0 {
0.0
} else {
(self.current_usage as f64 / self.capacity as f64) * 100.0
}
}
#[inline]
pub fn peak_utilization_rate(&self) -> f64 {
if self.capacity == 0 {
0.0
} else {
(self.peak_usage as f64 / self.capacity as f64) * 100.0
}
}
#[inline]
pub fn hit_rate(&self) -> f64 {
let total_attempts = self.total_allocations + self.allocation_failures;
if total_attempts == 0 {
1.0
} else {
self.total_allocations as f64 / total_attempts as f64
}
}
#[inline]
pub fn available(&self) -> usize {
self.capacity.saturating_sub(self.current_usage)
}
}
impl fmt::Display for PoolStatistics {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Pool Statistics:")?;
writeln!(f, " Capacity: {}", self.capacity)?;
writeln!(
f,
" Current Usage: {} ({:.1}%)",
self.current_usage,
self.utilization_rate()
)?;
writeln!(
f,
" Peak Usage: {} ({:.1}%)",
self.peak_usage,
self.peak_utilization_rate()
)?;
writeln!(f, " Total Allocations: {}", self.total_allocations)?;
writeln!(f, " Total Deallocations: {}", self.total_deallocations)?;
writeln!(f, " Allocation Failures: {}", self.allocation_failures)?;
writeln!(f, " Hit Rate: {:.2}%", self.hit_rate() * 100.0)?;
writeln!(f, " Growth Count: {}", self.growth_count)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn statistics_utilization() {
let stats = PoolStatistics {
capacity: 100,
current_usage: 50,
peak_usage: 75,
..PoolStatistics::new(100)
};
assert_eq!(stats.utilization_rate(), 50.0);
assert_eq!(stats.peak_utilization_rate(), 75.0);
}
#[test]
fn statistics_hit_rate() {
let stats = PoolStatistics {
total_allocations: 90,
allocation_failures: 10,
..PoolStatistics::new(100)
};
assert_eq!(stats.hit_rate(), 0.9);
}
#[test]
fn statistics_available() {
let stats = PoolStatistics {
capacity: 100,
current_usage: 30,
..PoolStatistics::new(100)
};
assert_eq!(stats.available(), 70);
}
}