scirs2_sparse/realtime_performance_monitor/
config.rs1#[derive(Debug, Clone)]
8pub struct PerformanceMonitorConfig {
9 pub monitoring_interval_ms: u64,
11 pub max_samples: usize,
13 pub adaptive_tuning: bool,
15 pub adaptation_threshold: f64,
17 pub enable_alerts: bool,
19 pub alert_threshold: f64,
21 pub auto_optimization: bool,
23 pub optimization_interval_s: u64,
25 pub enable_prediction: bool,
27 pub prediction_horizon: usize,
29 pub enable_system_metrics: bool,
31 pub enable_anomaly_detection: bool,
33 pub anomaly_sensitivity: f64,
35 pub max_alert_history: usize,
37 pub max_adaptation_history: usize,
39}
40
41impl Default for PerformanceMonitorConfig {
42 fn default() -> Self {
43 Self {
44 monitoring_interval_ms: 100,
45 max_samples: 10000,
46 adaptive_tuning: true,
47 adaptation_threshold: 0.8,
48 enable_alerts: true,
49 alert_threshold: 0.5,
50 auto_optimization: true,
51 optimization_interval_s: 30,
52 enable_prediction: true,
53 prediction_horizon: 50,
54 enable_system_metrics: true,
55 enable_anomaly_detection: true,
56 anomaly_sensitivity: 0.7,
57 max_alert_history: 1000,
58 max_adaptation_history: 500,
59 }
60 }
61}
62
63impl PerformanceMonitorConfig {
64 pub fn new() -> Self {
66 Default::default()
67 }
68
69 pub fn lightweight() -> Self {
71 Self {
72 monitoring_interval_ms: 500,
73 max_samples: 1000,
74 adaptive_tuning: false,
75 adaptation_threshold: 0.9,
76 enable_alerts: false,
77 alert_threshold: 0.3,
78 auto_optimization: false,
79 optimization_interval_s: 300,
80 enable_prediction: false,
81 prediction_horizon: 10,
82 enable_system_metrics: false,
83 enable_anomaly_detection: false,
84 anomaly_sensitivity: 0.5,
85 max_alert_history: 100,
86 max_adaptation_history: 50,
87 }
88 }
89
90 pub fn high_performance() -> Self {
92 Self {
93 monitoring_interval_ms: 50,
94 max_samples: 50000,
95 adaptive_tuning: true,
96 adaptation_threshold: 0.7,
97 enable_alerts: true,
98 alert_threshold: 0.6,
99 auto_optimization: true,
100 optimization_interval_s: 10,
101 enable_prediction: true,
102 prediction_horizon: 100,
103 enable_system_metrics: true,
104 enable_anomaly_detection: true,
105 anomaly_sensitivity: 0.8,
106 max_alert_history: 5000,
107 max_adaptation_history: 2000,
108 }
109 }
110
111 pub fn debug() -> Self {
113 Self {
114 monitoring_interval_ms: 10,
115 max_samples: 100000,
116 adaptive_tuning: true,
117 adaptation_threshold: 0.6,
118 enable_alerts: true,
119 alert_threshold: 0.7,
120 auto_optimization: true,
121 optimization_interval_s: 5,
122 enable_prediction: true,
123 prediction_horizon: 200,
124 enable_system_metrics: true,
125 enable_anomaly_detection: true,
126 anomaly_sensitivity: 0.9,
127 max_alert_history: 10000,
128 max_adaptation_history: 5000,
129 }
130 }
131
132 pub fn with_monitoring_interval_ms(mut self, interval: u64) -> Self {
134 self.monitoring_interval_ms = interval;
135 self
136 }
137
138 pub fn with_max_samples(mut self, max_samples: usize) -> Self {
139 self.max_samples = max_samples;
140 self
141 }
142
143 pub fn with_adaptive_tuning(mut self, enabled: bool) -> Self {
144 self.adaptive_tuning = enabled;
145 self
146 }
147
148 pub fn with_adaptation_threshold(mut self, threshold: f64) -> Self {
149 self.adaptation_threshold = threshold;
150 self
151 }
152
153 pub fn with_alerts(mut self, enabled: bool) -> Self {
154 self.enable_alerts = enabled;
155 self
156 }
157
158 pub fn with_alert_threshold(mut self, threshold: f64) -> Self {
159 self.alert_threshold = threshold;
160 self
161 }
162
163 pub fn with_auto_optimization(mut self, enabled: bool) -> Self {
164 self.auto_optimization = enabled;
165 self
166 }
167
168 pub fn with_optimization_interval_s(mut self, interval: u64) -> Self {
169 self.optimization_interval_s = interval;
170 self
171 }
172
173 pub fn with_prediction(mut self, enabled: bool) -> Self {
174 self.enable_prediction = enabled;
175 self
176 }
177
178 pub fn with_prediction_horizon(mut self, horizon: usize) -> Self {
179 self.prediction_horizon = horizon;
180 self
181 }
182
183 pub fn with_system_metrics(mut self, enabled: bool) -> Self {
184 self.enable_system_metrics = enabled;
185 self
186 }
187
188 pub fn with_anomaly_detection(mut self, enabled: bool) -> Self {
189 self.enable_anomaly_detection = enabled;
190 self
191 }
192
193 pub fn with_anomaly_sensitivity(mut self, sensitivity: f64) -> Self {
194 self.anomaly_sensitivity = sensitivity.clamp(0.0, 1.0);
195 self
196 }
197
198 pub fn validate(&self) -> Result<(), String> {
200 if self.monitoring_interval_ms == 0 {
201 return Err("Monitoring interval must be greater than 0".to_string());
202 }
203
204 if self.max_samples == 0 {
205 return Err("Max samples must be greater than 0".to_string());
206 }
207
208 if !(0.0..=1.0).contains(&self.adaptation_threshold) {
209 return Err("Adaptation threshold must be between 0.0 and 1.0".to_string());
210 }
211
212 if !(0.0..=1.0).contains(&self.alert_threshold) {
213 return Err("Alert threshold must be between 0.0 and 1.0".to_string());
214 }
215
216 if self.optimization_interval_s == 0 && self.auto_optimization {
217 return Err(
218 "Optimization interval must be greater than 0 when auto-optimization is enabled"
219 .to_string(),
220 );
221 }
222
223 if self.prediction_horizon == 0 && self.enable_prediction {
224 return Err(
225 "Prediction horizon must be greater than 0 when prediction is enabled".to_string(),
226 );
227 }
228
229 if !(0.0..=1.0).contains(&self.anomaly_sensitivity) {
230 return Err("Anomaly sensitivity must be between 0.0 and 1.0".to_string());
231 }
232
233 if self.max_alert_history == 0 && self.enable_alerts {
234 return Err(
235 "Max alert history must be greater than 0 when alerts are enabled".to_string(),
236 );
237 }
238
239 if self.max_adaptation_history == 0 && self.adaptive_tuning {
240 return Err(
241 "Max adaptation history must be greater than 0 when adaptive tuning is enabled"
242 .to_string(),
243 );
244 }
245
246 Ok(())
247 }
248
249 pub fn estimated_memory_usage(&self) -> usize {
251 let sample_size = std::mem::size_of::<super::metrics::PerformanceSample>();
252 let alert_size = std::mem::size_of::<super::alerts::Alert>();
253 let adaptation_size = 256; self.max_samples * sample_size
256 + self.max_alert_history * alert_size
257 + self.max_adaptation_history * adaptation_size
258 + 8192 }
260
261 pub fn is_realtime_suitable(&self) -> bool {
263 self.monitoring_interval_ms <= 1000 &&
266 self.estimated_memory_usage() <= 100 * 1024 * 1024 && self.max_samples <= 50000
268 }
269
270 pub fn recommended_for_use_case(use_case: UseCase) -> Self {
272 match use_case {
273 UseCase::Production => Self::default(),
274 UseCase::Development => Self::debug(),
275 UseCase::Testing => Self::lightweight(),
276 UseCase::Benchmarking => Self::high_performance(),
277 UseCase::LowResource => Self::lightweight().with_max_samples(500),
278 }
279 }
280}
281
282#[derive(Debug, Clone, Copy)]
284pub enum UseCase {
285 Production,
287 Development,
289 Testing,
291 Benchmarking,
293 LowResource,
295}
296
297#[cfg(test)]
298mod tests {
299 use super::*;
300
301 #[test]
302 fn test_default_config() {
303 let config = PerformanceMonitorConfig::default();
304 assert!(config.validate().is_ok());
305 assert_eq!(config.monitoring_interval_ms, 100);
306 assert_eq!(config.max_samples, 10000);
307 assert!(config.adaptive_tuning);
308 assert!(config.enable_alerts);
309 }
310
311 #[test]
312 fn test_lightweight_config() {
313 let config = PerformanceMonitorConfig::lightweight();
314 assert!(config.validate().is_ok());
315 assert_eq!(config.monitoring_interval_ms, 500);
316 assert_eq!(config.max_samples, 1000);
317 assert!(!config.adaptive_tuning);
318 assert!(!config.enable_alerts);
319 }
320
321 #[test]
322 fn test_high_performance_config() {
323 let config = PerformanceMonitorConfig::high_performance();
324 assert!(config.validate().is_ok());
325 assert_eq!(config.monitoring_interval_ms, 50);
326 assert_eq!(config.max_samples, 50000);
327 assert!(config.adaptive_tuning);
328 assert!(config.enable_alerts);
329 }
330
331 #[test]
332 fn test_builder_pattern() {
333 let config = PerformanceMonitorConfig::new()
334 .with_monitoring_interval_ms(200)
335 .with_max_samples(5000)
336 .with_adaptive_tuning(false)
337 .with_alerts(false);
338
339 assert!(config.validate().is_ok());
340 assert_eq!(config.monitoring_interval_ms, 200);
341 assert_eq!(config.max_samples, 5000);
342 assert!(!config.adaptive_tuning);
343 assert!(!config.enable_alerts);
344 }
345
346 #[test]
347 fn test_config_validation() {
348 let mut config = PerformanceMonitorConfig::default();
349 assert!(config.validate().is_ok());
350
351 config.monitoring_interval_ms = 0;
353 assert!(config.validate().is_err());
354
355 config.monitoring_interval_ms = 100;
356 config.max_samples = 0;
357 assert!(config.validate().is_err());
358
359 config.max_samples = 1000;
360 config.adaptation_threshold = 1.5;
361 assert!(config.validate().is_err());
362
363 config.adaptation_threshold = 0.8;
364 config.alert_threshold = -0.1;
365 assert!(config.validate().is_err());
366 }
367
368 #[test]
369 fn test_memory_usage_estimation() {
370 let config = PerformanceMonitorConfig::default();
371 let memory_usage = config.estimated_memory_usage();
372 assert!(memory_usage > 0);
373
374 let lightweight = PerformanceMonitorConfig::lightweight();
375 let lightweight_memory = lightweight.estimated_memory_usage();
376 assert!(lightweight_memory < memory_usage);
377 }
378
379 #[test]
380 fn test_realtime_suitability() {
381 let config = PerformanceMonitorConfig::default();
382 assert!(config.is_realtime_suitable());
383
384 let debug_config = PerformanceMonitorConfig::debug();
385 let _ = debug_config.is_realtime_suitable(); }
388
389 #[test]
390 fn test_use_case_recommendations() {
391 let production = PerformanceMonitorConfig::recommended_for_use_case(UseCase::Production);
392 assert!(production.validate().is_ok());
393
394 let development = PerformanceMonitorConfig::recommended_for_use_case(UseCase::Development);
395 assert!(development.validate().is_ok());
396
397 let testing = PerformanceMonitorConfig::recommended_for_use_case(UseCase::Testing);
398 assert!(testing.validate().is_ok());
399
400 let benchmarking =
401 PerformanceMonitorConfig::recommended_for_use_case(UseCase::Benchmarking);
402 assert!(benchmarking.validate().is_ok());
403
404 let low_resource = PerformanceMonitorConfig::recommended_for_use_case(UseCase::LowResource);
405 assert!(low_resource.validate().is_ok());
406 assert_eq!(low_resource.max_samples, 500);
407 }
408
409 #[test]
410 fn test_anomaly_sensitivity_clamping() {
411 let config = PerformanceMonitorConfig::new().with_anomaly_sensitivity(1.5); assert_eq!(config.anomaly_sensitivity, 1.0);
413
414 let config = PerformanceMonitorConfig::new().with_anomaly_sensitivity(-0.1); assert_eq!(config.anomaly_sensitivity, 0.0);
416 }
417}