use crate::snapshot::{GlobalSnapshot, ProcSnapshot};
#[derive(Debug, Clone, Copy, Default)]
pub struct MinMax(pub Option<u64>, Option<u64>);
impl MinMax {
pub fn update(&mut self, value: u64) {
self.0 = Some(self.0.map_or(value, |m| m.min(value)));
self.1 = Some(self.1.map_or(value, |m| m.max(value)));
}
pub fn reset(&mut self) {
self.0 = None;
self.1 = None;
}
pub fn min(&self) -> Option<u64> {
self.0
}
pub fn max(&self) -> Option<u64> {
self.1
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct ProcCounters {
pub vm_size: MinMax,
pub rss: MinMax,
pub pss: MinMax,
pub shared: MinMax,
pub anon: MinMax,
pub begin_read_bytes: u64,
pub begin_write_bytes: u64,
pub end_read_bytes: u64,
pub end_write_bytes: u64,
}
impl ProcCounters {
pub fn update(&mut self, snapshot: &ProcSnapshot) {
self.vm_size.update(snapshot.vm_size);
self.rss.update(snapshot.rss);
self.pss.update(snapshot.pss);
self.shared.update(snapshot.shared);
self.anon.update(snapshot.anon);
self.end_read_bytes = self.end_read_bytes.max(snapshot.read_bytes);
self.end_write_bytes = self.end_write_bytes.max(snapshot.write_bytes);
}
pub fn reset(&mut self) {
self.vm_size.reset();
self.rss.reset();
self.pss.reset();
self.shared.reset();
self.anon.reset();
self.begin_read_bytes = self.end_read_bytes;
self.begin_write_bytes = self.end_write_bytes;
}
}
pub fn compute_mem_used(
mem_total: u64,
mem_available: Option<MinMax>,
mem_free: MinMax,
cached: MinMax,
) -> MinMax {
if let Some(available) = mem_available {
MinMax(
Some(mem_total.saturating_sub(available.max().unwrap_or_default())),
Some(mem_total.saturating_sub(available.min().unwrap_or_default())),
)
} else {
MinMax(
Some(mem_total.saturating_sub(
mem_free.max().unwrap_or_default() + cached.max().unwrap_or_default(),
)),
Some(mem_total.saturating_sub(
mem_free.min().unwrap_or_default() + cached.min().unwrap_or_default(),
)),
)
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct GlobalCounters {
pub mem_available: Option<MinMax>,
pub mem_free: MinMax,
pub cached: MinMax,
pub anon: Option<MinMax>,
pub swap_free: MinMax,
}
impl GlobalCounters {
pub fn update(&mut self, snapshot: &GlobalSnapshot) {
self.mem_free.update(snapshot.mem_free);
self.cached.update(snapshot.cached);
self.swap_free.update(snapshot.swap_free);
if let Some(v) = snapshot.mem_available {
self.mem_available.get_or_insert_default().update(v);
}
if let Some(v) = snapshot.anon {
self.anon.get_or_insert_default().update(v);
}
}
pub fn reset(&mut self) {
self.mem_free.reset();
self.cached.reset();
self.swap_free.reset();
if let Some(v) = &mut self.mem_available {
v.reset();
}
if let Some(v) = &mut self.anon {
v.reset();
}
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct Counters {
pub proc: ProcCounters,
pub global: GlobalCounters,
}
impl Counters {
pub fn update(&mut self, proc: &ProcSnapshot, global: &GlobalSnapshot) {
self.proc.update(proc);
self.global.update(global);
}
pub fn reset(&mut self) {
self.proc.reset();
self.global.reset();
}
}