#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
#[non_exhaustive]
pub struct BinSnapshot {
pub alloc_count: u64,
pub dealloc_count: u64,
pub alloc_bytes: u64,
pub requested_bytes: u64,
pub block_size: usize,
pub live_estimate: u64,
}
impl BinSnapshot {
#[must_use]
pub fn saturating_delta(&self, baseline: &Self) -> Self {
Self {
alloc_count: self.alloc_count.saturating_sub(baseline.alloc_count),
dealloc_count: self.dealloc_count.saturating_sub(baseline.dealloc_count),
alloc_bytes: self.alloc_bytes.saturating_sub(baseline.alloc_bytes),
requested_bytes: self
.requested_bytes
.saturating_sub(baseline.requested_bytes),
block_size: self.block_size,
live_estimate: self.live_estimate.saturating_sub(baseline.live_estimate),
}
}
#[inline]
#[must_use]
pub fn fragmentation_ratio(&self) -> f64 {
if self.alloc_bytes == 0 {
return 0.0;
}
let live_bytes = self.live_estimate.saturating_mul(self.block_size as u64);
(live_bytes as f64 / self.alloc_bytes as f64).min(1.0)
}
#[inline]
#[must_use]
pub fn internal_fragmentation_ratio(&self) -> f64 {
if self.alloc_bytes == 0 || self.requested_bytes == 0 {
return 0.0;
}
let waste = self.alloc_bytes.saturating_sub(self.requested_bytes);
(waste as f64 / self.alloc_bytes as f64).min(1.0)
}
#[inline]
#[must_use]
pub fn live_bytes(&self) -> u64 {
self.live_estimate.saturating_mul(self.block_size as u64)
}
}