pub use cargo_gamma_process::support;
use clap::ValueEnum;
use serde::Deserialize;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, ValueEnum, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum MemoryControl {
Off,
Measure,
#[default]
Enforce,
}
pub(crate) const fn implied_memory_control(memory_limit: Option<u64>, baseline_memory_limit: Option<u64>) -> Option<MemoryControl> {
if memory_limit.is_some() {
Some(MemoryControl::Enforce)
} else if baseline_memory_limit.is_some() {
Some(MemoryControl::Measure)
} else {
None
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum Demand {
Stated,
#[default]
Inherited,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct MemoryPolicy {
pub control: MemoryControl,
pub demand: Demand,
pub multiplier: f64,
pub headroom: u64,
pub limit: Option<u64>,
pub baseline_limit: Option<u64>,
}
pub const DEFAULT_HEADROOM: u64 = 128 * 1024 * 1024;
pub const DEFAULT_MULTIPLIER: f64 = 2.0;
impl Default for MemoryPolicy {
fn default() -> Self {
Self {
control: MemoryControl::default(),
demand: Demand::default(),
multiplier: DEFAULT_MULTIPLIER,
headroom: DEFAULT_HEADROOM,
limit: None,
baseline_limit: None,
}
}
}
impl MemoryPolicy {
#[must_use]
pub const fn measuring(&self) -> bool {
!matches!(self.control, MemoryControl::Off)
}
#[must_use]
pub const fn enforcing(&self) -> bool {
matches!(self.control, MemoryControl::Enforce)
}
#[must_use]
pub const fn disabled(&self) -> Self {
Self {
control: MemoryControl::Off,
..*self
}
}
#[must_use]
pub const fn insisted(&self) -> bool {
matches!(self.demand, Demand::Stated)
}
#[must_use]
pub fn ceiling(&self, peak: Option<u64>, calibrated: bool) -> Option<u64> {
if !self.enforcing() {
return None;
}
if let Some(fixed) = self.limit {
return Some(fixed);
}
if !calibrated {
return None;
}
let peak = peak?;
Some(scale(peak, self.multiplier).max(peak.saturating_add(self.headroom)))
}
}
fn scale(peak: u64, multiplier: f64) -> u64 {
#[expect(clippy::cast_precision_loss, reason = "a memory ceiling is not sensitive to its last few bytes")]
let scaled = peak as f64 * multiplier.max(1.0);
#[expect(clippy::cast_precision_loss, reason = "the comparison only needs to be right near the boundary")]
let most = u64::MAX as f64;
if !scaled.is_finite() || scaled >= most {
return u64::MAX;
}
#[expect(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
reason = "the value is finite, non-negative and below `u64::MAX` by the test above"
)]
let bytes = scaled as u64;
bytes
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn measuring_without_enforcing_never_produces_a_ceiling() {
let policy = MemoryPolicy {
control: MemoryControl::Measure,
..MemoryPolicy::default()
};
assert!(policy.measuring());
assert!(!policy.enforcing());
assert_eq!(policy.ceiling(Some(1024), true), None);
}
#[test]
fn the_default_policy_enforces_a_calibrated_ceiling() {
let policy = MemoryPolicy::default();
assert!(policy.measuring());
assert!(policy.enforcing());
assert!(policy.ceiling(Some(1024), true).is_some());
}
#[test]
fn switching_control_off_asks_the_platform_for_nothing() {
let policy = MemoryPolicy {
control: MemoryControl::Off,
..MemoryPolicy::default()
};
assert!(!policy.measuring());
assert!(!policy.enforcing());
assert_eq!(policy.ceiling(Some(1024), true), None);
}
#[test]
fn only_a_stated_policy_is_insisted_upon() {
let inherited = MemoryPolicy::default();
assert!(!inherited.insisted());
assert!(!inherited.disabled().measuring());
let stated = MemoryPolicy {
demand: Demand::Stated,
..MemoryPolicy::default()
};
assert!(stated.insisted());
assert!((stated.disabled().multiplier - stated.multiplier).abs() < f64::EPSILON);
}
#[test]
fn a_small_baseline_peak_gets_the_absolute_headroom() {
let policy = MemoryPolicy {
control: MemoryControl::Enforce,
..MemoryPolicy::default()
};
assert_eq!(
policy.ceiling(Some(4 * 1024 * 1024), true),
Some(4 * 1024 * 1024 + DEFAULT_HEADROOM)
);
}
#[test]
fn a_large_baseline_peak_gets_the_multiplier() {
let policy = MemoryPolicy {
control: MemoryControl::Enforce,
..MemoryPolicy::default()
};
let peak = 4 * 1024 * 1024 * 1024_u64;
assert_eq!(policy.ceiling(Some(peak), true), Some(peak * 2));
}
#[test]
fn an_uncalibrated_run_gets_no_derived_ceiling_but_keeps_an_explicit_one() {
let policy = MemoryPolicy {
control: MemoryControl::Enforce,
..MemoryPolicy::default()
};
assert_eq!(policy.ceiling(None, false), None);
assert_eq!(policy.ceiling(Some(4096), false), None);
let explicit = MemoryPolicy {
limit: Some(4096),
..policy
};
assert_eq!(explicit.ceiling(None, false), Some(4096));
}
#[test]
fn an_explicit_limit_overrides_whatever_the_baseline_measured() {
let policy = MemoryPolicy {
control: MemoryControl::Enforce,
limit: Some(999),
..MemoryPolicy::default()
};
assert_eq!(policy.ceiling(Some(4 * 1024 * 1024 * 1024), true), Some(999));
}
#[test]
fn scaling_saturates_and_never_shrinks_the_peak() {
assert_eq!(scale(1024, 0.5), 1024);
assert_eq!(scale(u64::MAX, 2.0), u64::MAX);
assert_eq!(scale(1024, f64::INFINITY), u64::MAX);
assert_eq!(scale(0, 2.0), 0);
}
#[test]
fn unsupported_hosts_say_why_rather_than_merely_saying_no() {
if let Err(reason) = support() {
let reason = reason.to_string();
assert!(reason.len() > 20, "{reason}");
}
}
}