use core::{alloc::GlobalAlloc, ops::Sub};
use crate::Heapster;
#[cfg(feature = "histograms")]
use crate::Histogram;
#[derive(Debug, Default, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Stats {
pub alloc_count: usize,
pub alloc_sum: u64,
pub alloc_avg: Option<usize>,
#[cfg(feature = "histograms")]
pub alloc_histogram: Histogram,
pub alloc_fail_count: usize,
pub dealloc_count: usize,
pub dealloc_sum: u64,
pub dealloc_avg: Option<usize>,
pub realloc_growth_count: usize,
pub realloc_growth_sum: u64,
pub realloc_growth_avg: Option<usize>,
#[cfg(feature = "histograms")]
pub realloc_growth_histogram: Histogram,
pub realloc_shrink_count: usize,
pub realloc_shrink_sum: u64,
pub realloc_shrink_avg: Option<usize>,
#[cfg(feature = "histograms")]
pub realloc_shrink_histogram: Histogram,
#[cfg(feature = "realloc_moves")]
pub realloc_move_count: usize,
#[cfg(feature = "realloc_moves")]
pub realloc_move_sum: u64,
#[cfg(feature = "realloc_moves")]
pub realloc_move_avg: Option<usize>,
pub realloc_fail_count: usize,
pub total_alloc_sum: u64,
pub total_dealloc_sum: u64,
pub use_curr: usize,
#[cfg(feature = "use_max")]
pub use_max: usize,
}
impl<A: GlobalAlloc> Heapster<A> {
pub fn stats(&self) -> Stats {
let alloc_count = self.alloc_count();
let alloc_sum = self.alloc_sum();
let alloc_avg = alloc_sum
.checked_div(alloc_count as u64)
.map(|avg| avg as usize);
#[cfg(feature = "histograms")]
let alloc_histogram = self.alloc_histogram();
let alloc_fail_count = self.alloc_fail_count();
let dealloc_count = self.dealloc_count();
let dealloc_sum = self.dealloc_sum();
let dealloc_avg = dealloc_sum
.checked_div(dealloc_count as u64)
.map(|avg| avg as usize);
let realloc_growth_count = self.realloc_growth_count();
let realloc_growth_sum = self.realloc_growth_sum();
let realloc_growth_avg = realloc_growth_sum
.checked_div(realloc_growth_count as u64)
.map(|avg| avg as usize);
#[cfg(feature = "histograms")]
let realloc_growth_histogram = self.realloc_growth_histogram();
let realloc_shrink_count = self.realloc_shrink_count();
let realloc_shrink_sum = self.realloc_shrink_sum();
let realloc_shrink_avg = realloc_shrink_sum
.checked_div(realloc_shrink_count as u64)
.map(|avg| avg as usize);
#[cfg(feature = "histograms")]
let realloc_shrink_histogram = self.realloc_shrink_histogram();
#[cfg(feature = "realloc_moves")]
let realloc_move_count = self.realloc_move_count();
#[cfg(feature = "realloc_moves")]
let realloc_move_sum = self.realloc_move_sum();
#[cfg(feature = "realloc_moves")]
let realloc_move_avg = realloc_move_sum
.checked_div(realloc_move_count as u64)
.map(|avg| avg as usize);
let realloc_fail_count = self.realloc_fail_count();
let total_alloc_sum = alloc_sum + realloc_growth_sum;
let total_dealloc_sum = dealloc_sum + realloc_shrink_sum;
let use_curr = self.use_curr();
#[cfg(feature = "use_max")]
let use_max = self.use_max();
Stats {
alloc_count,
alloc_sum,
alloc_avg,
#[cfg(feature = "histograms")]
alloc_histogram,
alloc_fail_count,
dealloc_count,
dealloc_sum,
dealloc_avg,
realloc_growth_count,
realloc_growth_sum,
realloc_growth_avg,
#[cfg(feature = "histograms")]
realloc_growth_histogram,
realloc_shrink_count,
realloc_shrink_sum,
realloc_shrink_avg,
#[cfg(feature = "histograms")]
realloc_shrink_histogram,
#[cfg(feature = "realloc_moves")]
realloc_move_count,
#[cfg(feature = "realloc_moves")]
realloc_move_sum,
#[cfg(feature = "realloc_moves")]
realloc_move_avg,
realloc_fail_count,
total_alloc_sum,
total_dealloc_sum,
use_curr,
#[cfg(feature = "use_max")]
use_max,
}
}
}
impl Sub<&Stats> for &Stats {
type Output = Stats;
fn sub(self, old: &Stats) -> Stats {
let alloc_count = self.alloc_count.saturating_sub(old.alloc_count);
let alloc_sum = self.alloc_sum.saturating_sub(old.alloc_sum);
let alloc_avg = alloc_sum
.checked_div(alloc_count as u64)
.map(|avg| avg as usize);
#[cfg(feature = "histograms")]
let alloc_histogram = self.alloc_histogram - old.alloc_histogram;
let alloc_fail_count = self.alloc_fail_count.saturating_sub(old.alloc_fail_count);
let dealloc_count = self.dealloc_count.saturating_sub(old.dealloc_count);
let dealloc_sum = self.dealloc_sum.saturating_sub(old.dealloc_sum);
let dealloc_avg = dealloc_sum
.checked_div(dealloc_count as u64)
.map(|avg| avg as usize);
let realloc_growth_count = self
.realloc_growth_count
.saturating_sub(old.realloc_growth_count);
let realloc_growth_sum = self
.realloc_growth_sum
.saturating_sub(old.realloc_growth_sum);
let realloc_growth_avg = realloc_growth_sum
.checked_div(realloc_growth_count as u64)
.map(|avg| avg as usize);
#[cfg(feature = "histograms")]
let realloc_growth_histogram = self.realloc_growth_histogram - old.realloc_growth_histogram;
let realloc_shrink_count = self
.realloc_shrink_count
.saturating_sub(old.realloc_shrink_count);
let realloc_shrink_sum = self
.realloc_shrink_sum
.saturating_sub(old.realloc_shrink_sum);
let realloc_shrink_avg = realloc_shrink_sum
.checked_div(realloc_shrink_count as u64)
.map(|avg| avg as usize);
#[cfg(feature = "histograms")]
let realloc_shrink_histogram = self.realloc_shrink_histogram - old.realloc_shrink_histogram;
#[cfg(feature = "realloc_moves")]
let realloc_move_count = self
.realloc_move_count
.saturating_sub(old.realloc_move_count);
#[cfg(feature = "realloc_moves")]
let realloc_move_sum = self.realloc_move_sum.saturating_sub(old.realloc_move_sum);
#[cfg(feature = "realloc_moves")]
let realloc_move_avg = realloc_move_sum
.checked_div(realloc_move_count as u64)
.map(|avg| avg as usize);
let realloc_fail_count = self
.realloc_fail_count
.saturating_sub(old.realloc_fail_count);
let total_alloc_sum = self.total_alloc_sum.saturating_sub(old.total_alloc_sum);
let total_dealloc_sum = self.total_dealloc_sum.saturating_sub(old.total_dealloc_sum);
#[cfg(feature = "use_max")]
let use_max = self.use_max.saturating_sub(old.use_max);
Stats {
alloc_count,
alloc_sum,
alloc_avg,
#[cfg(feature = "histograms")]
alloc_histogram,
alloc_fail_count,
dealloc_count,
dealloc_sum,
dealloc_avg,
realloc_growth_count,
realloc_growth_sum,
realloc_growth_avg,
#[cfg(feature = "histograms")]
realloc_growth_histogram,
realloc_shrink_count,
realloc_shrink_sum,
realloc_shrink_avg,
#[cfg(feature = "histograms")]
realloc_shrink_histogram,
#[cfg(feature = "realloc_moves")]
realloc_move_count,
#[cfg(feature = "realloc_moves")]
realloc_move_sum,
#[cfg(feature = "realloc_moves")]
realloc_move_avg,
realloc_fail_count,
total_alloc_sum,
total_dealloc_sum,
use_curr: self.use_curr,
#[cfg(feature = "use_max")]
use_max,
}
}
}
impl Sub<Stats> for Stats {
type Output = Stats;
fn sub(self, old: Stats) -> Stats {
&self - &old
}
}
impl Sub<&Stats> for Stats {
type Output = Stats;
fn sub(self, old: &Stats) -> Stats {
&self - old
}
}
impl Sub<Stats> for &Stats {
type Output = Stats;
fn sub(self, old: Stats) -> Stats {
self - &old
}
}