use super::ThrottleStateView;
pub type ThrottlingStrategy = fn(state: &ThrottleStateView) -> f64;
pub fn power_curve_strategy(state: &ThrottleStateView) -> f64 {
let curve = state.config.curve_factor;
let deviation = (state.current_balance as f64 - state.learned_balance).abs();
let severity = (deviation - state.config.healthy_balance_width as f64).max(0.0);
let max_sev = (state.config.max_imbalance - state.config.healthy_balance_width) as f64;
if max_sev <= 0.0 {
return if severity > 0.0 { 1.0 } else { 0.0 };
}
let x = (severity / max_sev).clamp(0.0, 1.0);
x.powf(curve)
}
pub fn linear_strategy(state: &ThrottleStateView) -> f64 {
let deviation = (state.current_balance as f64 - state.learned_balance).abs();
let severity = (deviation - state.config.healthy_balance_width as f64).max(0.0);
let max_possible_severity =
(state.config.max_imbalance - state.config.healthy_balance_width) as f64;
if max_possible_severity <= 0.0 {
return if severity > 0.0 { 1.0 } else { 0.0 };
}
(severity / max_possible_severity).clamp(0.0, 1.0)
}
#[cfg(test)]
mod additional_strategy_tests {
use super::*;
use crate::throttle::types::{AdaptiveThrottleConfig, ThrottleStateView};
#[test]
fn test_linear_strategy_scaling() {
let mut config = AdaptiveThrottleConfig::default();
config.healthy_balance_width = 10;
config.max_imbalance = 110;
let state_healthy = ThrottleStateView {
current_balance: 5,
learned_balance: 0.0,
config: &config,
};
assert_eq!(linear_strategy(&state_healthy), 0.0);
let state_half = ThrottleStateView {
current_balance: 60,
learned_balance: 0.0,
config: &config,
};
assert_eq!(linear_strategy(&state_half), 0.5);
let state_clamped = ThrottleStateView {
current_balance: 200,
learned_balance: 0.0,
config: &config,
};
assert_eq!(linear_strategy(&state_clamped), 1.0);
}
#[test]
fn test_power_curve_strategy_scaling() {
let mut config = AdaptiveThrottleConfig::default();
config.healthy_balance_width = 0;
config.max_imbalance = 100;
config.curve_factor = 2.0;
let state = ThrottleStateView {
current_balance: 50,
learned_balance: 0.0,
config: &config,
};
assert_eq!(power_curve_strategy(&state), 0.25);
}
}