use rand::{RngExt, rng};
#[derive(Clone)]
pub struct MemoryMetrics {
pub total_bytes: u64,
pub used_bytes: u64,
pub available_bytes: u64,
pub free_bytes: u64,
pub buffers_bytes: u64,
pub cached_bytes: u64,
pub swap_total_bytes: u64,
pub swap_used_bytes: u64,
pub swap_free_bytes: u64,
pub utilization: f32,
}
impl MemoryMetrics {
pub fn update(&mut self) {
let mut rng = rng();
let memory_util_delta = rng.random_range(-2.0..2.0);
self.utilization = (self.utilization + memory_util_delta).clamp(30.0, 102.0);
let target_used_bytes = (self.total_bytes as f64 * self.utilization as f64 / 100.0) as u64;
if target_used_bytes > self.total_bytes {
self.used_bytes = self.total_bytes;
self.available_bytes = 0;
self.free_bytes = 0;
if self.swap_total_bytes > 0 {
let excess_bytes = target_used_bytes - self.total_bytes;
self.swap_used_bytes = excess_bytes.min(self.swap_total_bytes);
self.swap_free_bytes = self.swap_total_bytes - self.swap_used_bytes;
self.utilization = 100.0;
} else {
self.utilization = 100.0;
}
} else {
self.used_bytes = target_used_bytes;
self.available_bytes = self.total_bytes - target_used_bytes;
let free_ratio = rng.random_range(0.3..0.8);
self.free_bytes = (self.available_bytes as f64 * free_ratio) as u64;
if self.swap_total_bytes > 0 {
self.swap_used_bytes = 0;
self.swap_free_bytes = self.swap_total_bytes;
}
}
if self.buffers_bytes > 0 {
let buffer_delta =
rng.random_range(-(self.total_bytes as i64 / 200)..(self.total_bytes as i64 / 200));
self.buffers_bytes = self
.buffers_bytes
.saturating_add_signed(buffer_delta)
.min(self.total_bytes / 20);
}
if self.cached_bytes > 0 {
let cache_delta =
rng.random_range(-(self.total_bytes as i64 / 100)..(self.total_bytes as i64 / 100));
self.cached_bytes = self
.cached_bytes
.saturating_add_signed(cache_delta)
.min(self.total_bytes / 5);
}
}
}