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 => vtcode_config::constants::memory::WARNING_TTL_REDUCTION_FACTOR,
55 MemoryPressure::Critical => vtcode_config::constants::memory::CRITICAL_TTL_REDUCTION_FACTOR,
56 }
57 }
58}
59
60impl fmt::Display for MemoryPressure {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 match self {
63 MemoryPressure::Normal => write!(f, "Normal"),
64 MemoryPressure::Warning => write!(f, "Warning"),
65 MemoryPressure::Critical => write!(f, "Critical"),
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_memory_pressure_from_rss_normal() {
76 let soft_limit = vtcode_config::constants::memory::SOFT_LIMIT_BYTES;
77 let pressure = MemoryPressure::from_rss(soft_limit - 1024); assert_eq!(pressure, MemoryPressure::Normal);
79 }
80
81 #[test]
82 fn test_memory_pressure_from_rss_warning() {
83 let soft_limit = vtcode_config::constants::memory::SOFT_LIMIT_BYTES;
84 let hard_limit = vtcode_config::constants::memory::HARD_LIMIT_BYTES;
85 let mid_point = (soft_limit + hard_limit) / 2;
86 let pressure = MemoryPressure::from_rss(mid_point);
87 assert_eq!(pressure, MemoryPressure::Warning);
88 }
89
90 #[test]
91 fn test_memory_pressure_from_rss_critical() {
92 let hard_limit = vtcode_config::constants::memory::HARD_LIMIT_BYTES;
93 let pressure = MemoryPressure::from_rss(hard_limit + 1024); assert_eq!(pressure, MemoryPressure::Critical);
95 }
96
97 #[test]
98 fn test_should_evict() {
99 assert!(!MemoryPressure::Normal.should_evict());
100 assert!(MemoryPressure::Warning.should_evict());
101 assert!(MemoryPressure::Critical.should_evict());
102 }
103
104 #[test]
105 fn test_should_evict_aggressively() {
106 assert!(!MemoryPressure::Normal.should_evict_aggressively());
107 assert!(!MemoryPressure::Warning.should_evict_aggressively());
108 assert!(MemoryPressure::Critical.should_evict_aggressively());
109 }
110
111 #[test]
112 fn test_ttl_reduction_factors() {
113 let normal_factor = MemoryPressure::Normal.ttl_reduction_factor();
114 let warning_factor = MemoryPressure::Warning.ttl_reduction_factor();
115 let critical_factor = MemoryPressure::Critical.ttl_reduction_factor();
116
117 assert!(normal_factor > warning_factor);
119 assert!(warning_factor > critical_factor);
120
121 assert!(normal_factor <= 1.0);
123 assert!(critical_factor > 0.0);
124 }
125
126 #[test]
127 fn test_display() {
128 assert_eq!(format!("{}", MemoryPressure::Normal), "Normal");
129 assert_eq!(format!("{}", MemoryPressure::Warning), "Warning");
130 assert_eq!(format!("{}", MemoryPressure::Critical), "Critical");
131 }
132}