vtcode_core/memory/
pressure.rs1use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum MemoryPressure {
8 Normal,
10 Warning,
12 Critical,
14}
15
16impl MemoryPressure {
17 pub fn from_rss(rss_bytes: usize) -> Self {
19 let soft_limit = vtcode_config::constants::memory::SOFT_LIMIT_BYTES;
20 let hard_limit = vtcode_config::constants::memory::HARD_LIMIT_BYTES;
21
22 if rss_bytes >= hard_limit {
23 MemoryPressure::Critical
24 } else if rss_bytes >= soft_limit {
25 MemoryPressure::Warning
26 } else {
27 MemoryPressure::Normal
28 }
29 }
30
31 pub fn should_evict(&self) -> bool {
33 matches!(self, MemoryPressure::Warning | MemoryPressure::Critical)
34 }
35
36 pub fn should_evict_aggressively(&self) -> bool {
38 matches!(self, MemoryPressure::Critical)
39 }
40
41 pub fn description(&self) -> &'static str {
43 match self {
44 MemoryPressure::Normal => "Normal (memory usage is healthy)",
45 MemoryPressure::Warning => "Warning (approaching soft limit, consider cleanup)",
46 MemoryPressure::Critical => "Critical (at hard limit, aggressive cleanup recommended)",
47 }
48 }
49
50 pub fn ttl_reduction_factor(&self) -> f64 {
52 match self {
53 MemoryPressure::Normal => 1.0,
54 MemoryPressure::Warning => {
55 vtcode_config::constants::memory::WARNING_TTL_REDUCTION_FACTOR
56 }
57 MemoryPressure::Critical => {
58 vtcode_config::constants::memory::CRITICAL_TTL_REDUCTION_FACTOR
59 }
60 }
61 }
62}
63
64impl fmt::Display for MemoryPressure {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 match self {
67 MemoryPressure::Normal => write!(f, "Normal"),
68 MemoryPressure::Warning => write!(f, "Warning"),
69 MemoryPressure::Critical => write!(f, "Critical"),
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_memory_pressure_from_rss_normal() {
80 let soft_limit = vtcode_config::constants::memory::SOFT_LIMIT_BYTES;
81 let pressure = MemoryPressure::from_rss(soft_limit - 1024); assert_eq!(pressure, MemoryPressure::Normal);
83 }
84
85 #[test]
86 fn test_memory_pressure_from_rss_warning() {
87 let soft_limit = vtcode_config::constants::memory::SOFT_LIMIT_BYTES;
88 let hard_limit = vtcode_config::constants::memory::HARD_LIMIT_BYTES;
89 let mid_point = (soft_limit + hard_limit) / 2;
90 let pressure = MemoryPressure::from_rss(mid_point);
91 assert_eq!(pressure, MemoryPressure::Warning);
92 }
93
94 #[test]
95 fn test_memory_pressure_from_rss_critical() {
96 let hard_limit = vtcode_config::constants::memory::HARD_LIMIT_BYTES;
97 let pressure = MemoryPressure::from_rss(hard_limit + 1024); assert_eq!(pressure, MemoryPressure::Critical);
99 }
100
101 #[test]
102 fn test_should_evict() {
103 assert!(!MemoryPressure::Normal.should_evict());
104 assert!(MemoryPressure::Warning.should_evict());
105 assert!(MemoryPressure::Critical.should_evict());
106 }
107
108 #[test]
109 fn test_should_evict_aggressively() {
110 assert!(!MemoryPressure::Normal.should_evict_aggressively());
111 assert!(!MemoryPressure::Warning.should_evict_aggressively());
112 assert!(MemoryPressure::Critical.should_evict_aggressively());
113 }
114
115 #[test]
116 fn test_ttl_reduction_factors() {
117 let normal_factor = MemoryPressure::Normal.ttl_reduction_factor();
118 let warning_factor = MemoryPressure::Warning.ttl_reduction_factor();
119 let critical_factor = MemoryPressure::Critical.ttl_reduction_factor();
120
121 assert!(normal_factor > warning_factor);
123 assert!(warning_factor > critical_factor);
124
125 assert!(normal_factor <= 1.0);
127 assert!(critical_factor > 0.0);
128 }
129
130 #[test]
131 fn test_display() {
132 assert_eq!(format!("{}", MemoryPressure::Normal), "Normal");
133 assert_eq!(format!("{}", MemoryPressure::Warning), "Warning");
134 assert_eq!(format!("{}", MemoryPressure::Critical), "Critical");
135 }
136}