pub mod promotion;
pub use promotion::{PromotionCandidate, PromotionConfig, PromotionEngine, PromotionInput};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum CompressionLevel {
Episodic,
Procedural,
Declarative,
}
impl CompressionLevel {
#[must_use]
pub fn cost_factor(self) -> f32 {
match self {
Self::Episodic => 1.0,
Self::Procedural => 0.6,
Self::Declarative => 0.3,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct RetrievalPolicy {
pub low_budget_ratio: f32,
pub mid_budget_ratio: f32,
}
impl Default for RetrievalPolicy {
fn default() -> Self {
Self {
low_budget_ratio: 0.20,
mid_budget_ratio: 0.50,
}
}
}
impl RetrievalPolicy {
#[tracing::instrument(name = "memory.compression.select", skip_all, fields(remaining_ratio))]
pub fn select(&self, remaining_ratio: f32) -> &'static [CompressionLevel] {
if remaining_ratio < self.low_budget_ratio {
&[CompressionLevel::Episodic]
} else if remaining_ratio < self.mid_budget_ratio {
&[CompressionLevel::Episodic, CompressionLevel::Procedural]
} else {
&[
CompressionLevel::Episodic,
CompressionLevel::Procedural,
CompressionLevel::Declarative,
]
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compression_level_cost_factors() {
assert!((CompressionLevel::Episodic.cost_factor() - 1.0).abs() < 1e-6);
assert!((CompressionLevel::Procedural.cost_factor() - 0.6).abs() < 1e-6);
assert!((CompressionLevel::Declarative.cost_factor() - 0.3).abs() < 1e-6);
}
#[test]
fn retrieval_policy_full_budget() {
let policy = RetrievalPolicy::default();
let levels = policy.select(0.80);
assert!(levels.contains(&CompressionLevel::Episodic));
assert!(levels.contains(&CompressionLevel::Procedural));
assert!(levels.contains(&CompressionLevel::Declarative));
}
#[test]
fn retrieval_policy_mid_budget() {
let policy = RetrievalPolicy::default();
let levels = policy.select(0.35);
assert!(levels.contains(&CompressionLevel::Episodic));
assert!(levels.contains(&CompressionLevel::Procedural));
assert!(!levels.contains(&CompressionLevel::Declarative));
}
#[test]
fn retrieval_policy_low_budget() {
let policy = RetrievalPolicy::default();
let levels = policy.select(0.10);
assert_eq!(levels, &[CompressionLevel::Episodic]);
}
#[test]
fn retrieval_policy_boundary_at_low() {
let policy = RetrievalPolicy::default();
let levels = policy.select(0.20);
assert!(levels.contains(&CompressionLevel::Procedural));
}
#[test]
fn retrieval_policy_boundary_at_mid() {
let policy = RetrievalPolicy::default();
let levels = policy.select(0.50);
assert!(levels.contains(&CompressionLevel::Declarative));
}
}