use super::compute::{compute_index_memory_limit_mb, compute_memory_limit_mb};
use super::constants::{FALLBACK_RAM_MB, MINIMUM_SUPPORTED_RAM_MB};
use super::detect::detect_total_ram_mb;
use super::tier::MemoryTier;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct MachineBudget {
pub total_ram_mb: u64,
pub tier: MemoryTier,
pub memory_limit_mb: usize,
pub index_memory_limit_mb: usize,
}
impl MachineBudget {
pub fn detect() -> Self {
let total_ram_mb = detect_total_ram_mb().unwrap_or_else(|| {
tracing::warn!(
"machine_tier: could not detect total system RAM — \
falling back to {FALLBACK_RAM_MB} MB (Degraded tier)"
);
FALLBACK_RAM_MB
});
Self::from_total_ram_mb(total_ram_mb)
}
pub fn from_total_ram_mb(total_ram_mb: u64) -> Self {
Self {
total_ram_mb,
tier: MemoryTier::from_total_ram_mb(total_ram_mb),
memory_limit_mb: compute_memory_limit_mb(total_ram_mb),
index_memory_limit_mb: compute_index_memory_limit_mb(total_ram_mb),
}
}
pub fn is_below_minimum(&self) -> bool {
self.total_ram_mb < MINIMUM_SUPPORTED_RAM_MB
}
pub fn minimum_advisory(&self) -> Option<String> {
if !self.is_below_minimum() {
return None;
}
Some(format!(
"detected {} MB ({:.1} GB) of usable RAM, below the {} GB minimum — \
running in the {} tier with reduced caps. The supported target is {} GB. \
Indexing large codebases on this host will be slower and may evict \
resident state aggressively.",
self.total_ram_mb,
self.total_ram_mb as f64 / 1024.0,
MINIMUM_SUPPORTED_RAM_MB / 1024,
self.tier,
super::constants::SUPPORTED_TARGET_RAM_MB / 1024,
))
}
}