formualizer_eval/engine/
warmup.rs1use crate::engine::cache::{CriteriaKey, CriteriaMaskCache};
4use crate::engine::masks::DenseMask;
5use crate::engine::metrics::{WarmupMetrics, WarmupTimer};
6use crate::engine::pass_planner::PassWarmupPlan;
7use crate::engine::tuning::WarmupConfig;
8use crate::traits::FunctionContext;
9use std::collections::HashSet;
10use std::sync::{Arc, Condvar, Mutex};
11use std::time::{Duration, Instant};
12
13#[derive(Default)]
15struct BuildCoordinator {
16 in_flight: Mutex<HashSet<String>>,
18 cv: Condvar,
20}
21
22impl BuildCoordinator {
23 fn try_claim(&self, key: &str) -> bool {
25 let mut in_flight = self.in_flight.lock().unwrap();
26 if in_flight.contains(key) {
27 false
28 } else {
29 in_flight.insert(key.to_string());
30 true
31 }
32 }
33
34 fn wait_for(&self, key: &str, timeout: Duration) -> bool {
36 let start = Instant::now();
37 let mut in_flight = self.in_flight.lock().unwrap();
38
39 while in_flight.contains(key) {
40 let remaining = timeout.saturating_sub(start.elapsed());
41 if remaining.is_zero() {
42 return false; }
44
45 let (guard, timeout_result) = self.cv.wait_timeout(in_flight, remaining).unwrap();
46 in_flight = guard;
47
48 if timeout_result.timed_out() {
49 return false;
50 }
51 }
52 true
53 }
54
55 fn release(&self, key: &str) {
57 let mut in_flight = self.in_flight.lock().unwrap();
58 in_flight.remove(key);
59 self.cv.notify_all();
60 }
61}
62
63pub struct PassContext {
65 pub mask_cache: CriteriaMaskCache,
66 pub metrics: Arc<WarmupMetrics>,
67 mask_coordinator: Arc<BuildCoordinator>,
69}
70
71impl PassContext {
72 pub fn new(config: &WarmupConfig) -> Self {
73 Self {
74 mask_cache: CriteriaMaskCache::new(config.mask_cache_entries_cap),
75 metrics: Arc::new(WarmupMetrics::new()),
76 mask_coordinator: Arc::new(BuildCoordinator::default()),
77 }
78 }
79
80 pub fn clear(&mut self) {
82 self.mask_cache.clear();
83 self.metrics.reset();
84 }
85
86 pub fn get_or_build_mask<C: FunctionContext>(
88 &mut self,
89 key: &CriteriaKey,
90 _context: &C,
91 _config: &WarmupConfig,
92 ) -> Option<DenseMask> {
93 if let Some(mask) = self.mask_cache.get(key) {
95 self.metrics.record_mask_reuse();
96 return Some(mask);
97 }
98
99 None
102 }
103}
104
105pub struct WarmupExecutor {
107 config: WarmupConfig,
108}
109
110impl WarmupExecutor {
111 pub fn new(config: WarmupConfig) -> Self {
112 Self { config }
113 }
114
115 pub fn execute<C: FunctionContext>(
117 &self,
118 plan: &PassWarmupPlan,
119 pass_ctx: &mut PassContext,
120 context: &C,
121 ) -> Result<(), String> {
122 if !self.config.warmup_enabled {
123 return Ok(());
124 }
125
126 let timer = WarmupTimer::start();
127 pass_ctx.metrics.record_warmup_time(timer.elapsed());
131
132 Ok(())
133 }
134}
135
136