lean_ctx/core/context_kernel/
adaptive_bridge.rs1use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
4
5use super::kernel_config;
6
7static BOUNCE_RATE_BITS: AtomicU64 = AtomicU64::new(0.0_f64.to_bits());
8static SIGNALS_RECEIVED: AtomicUsize = AtomicUsize::new(0);
9
10#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize)]
12pub enum KernelCompressionAdvice {
13 #[default]
15 Maintain,
16 Reduce,
18 Increase,
20}
21
22#[derive(Debug, Clone, Default, serde::Serialize)]
24pub struct AdaptiveSummary {
25 pub current_bounce_rate: f64,
27 pub advice: KernelCompressionAdvice,
29 pub signals_received: usize,
31}
32
33#[must_use]
35pub fn compression_advice(bounce_rate: f64) -> KernelCompressionAdvice {
36 if !kernel_config::is_enabled() {
37 return KernelCompressionAdvice::Maintain;
38 }
39 if bounce_rate > 0.3 {
40 KernelCompressionAdvice::Reduce
41 } else if bounce_rate < 0.05 {
42 KernelCompressionAdvice::Increase
43 } else {
44 KernelCompressionAdvice::Maintain
45 }
46}
47
48pub fn update_bounce_signal(bounce_rate: f64) {
50 BOUNCE_RATE_BITS.store(bounce_rate.to_bits(), Ordering::Relaxed);
51 SIGNALS_RECEIVED.fetch_add(1, Ordering::Relaxed);
52}
53
54#[must_use]
56pub fn current_bounce_rate() -> f64 {
57 f64::from_bits(BOUNCE_RATE_BITS.load(Ordering::Relaxed))
58}
59
60#[must_use]
62pub fn adaptive_summary() -> AdaptiveSummary {
63 let current_bounce_rate = current_bounce_rate();
64 AdaptiveSummary {
65 current_bounce_rate,
66 advice: compression_advice(current_bounce_rate),
67 signals_received: SIGNALS_RECEIVED.load(Ordering::Relaxed),
68 }
69}
70
71pub fn reset() {
73 BOUNCE_RATE_BITS.store(0.0_f64.to_bits(), Ordering::Relaxed);
74 SIGNALS_RECEIVED.store(0, Ordering::Relaxed);
75}
76
77#[cfg(test)]
78mod tests {
79 use super::{
80 KernelCompressionAdvice, adaptive_summary, compression_advice, reset, update_bounce_signal,
81 };
82 use crate::core::context_kernel::kernel_config::{self, KernelFeatures};
83
84 fn setup() -> std::sync::MutexGuard<'static, ()> {
85 let guard = kernel_config::KERNEL_TEST_LOCK
86 .lock()
87 .unwrap_or_else(std::sync::PoisonError::into_inner);
88 kernel_config::reset_features();
89 reset();
90 guard
91 }
92
93 #[test]
94 fn high_bounce_advises_reduce() {
95 let _guard = setup();
96 assert_eq!(compression_advice(0.5), KernelCompressionAdvice::Reduce);
97 }
98
99 #[test]
100 fn low_bounce_advises_increase() {
101 let _guard = setup();
102 assert_eq!(compression_advice(0.01), KernelCompressionAdvice::Increase);
103 }
104
105 #[test]
106 fn moderate_bounce_maintains() {
107 let _guard = setup();
108 assert_eq!(compression_advice(0.15), KernelCompressionAdvice::Maintain);
109 }
110
111 #[test]
112 fn disabled_kernel_always_maintains() {
113 let _guard = setup();
114 let features = KernelFeatures {
115 enabled: false,
116 ..KernelFeatures::default()
117 };
118 kernel_config::update_features(features);
119 assert_eq!(compression_advice(0.9), KernelCompressionAdvice::Maintain);
120 }
121
122 #[test]
123 fn summary_reports_latest_signal_and_count() {
124 let _guard = setup();
125 update_bounce_signal(0.4);
126 update_bounce_signal(0.2);
127 let summary = adaptive_summary();
128 assert_eq!(summary.current_bounce_rate, 0.2);
129 assert_eq!(summary.advice, KernelCompressionAdvice::Maintain);
130 assert_eq!(summary.signals_received, 2);
131 }
132}