trellis_runner/engine/policy/
max_iter.rs1use super::EnginePolicy;
22
23use crate::engine::{EngineAction, EngineContext, EventBatch};
24
25pub struct MaxIterationPolicy {
26 max_iters: usize,
27}
28
29impl MaxIterationPolicy {
30 pub fn new(max_iters: usize) -> Self {
31 Self { max_iters }
32 }
33}
34
35impl<F> EnginePolicy<F> for MaxIterationPolicy {
36 fn decide(&mut self, _batch: &EventBatch<F>, context: &EngineContext) -> EngineAction {
37 if context.iter > self.max_iters {
38 return EngineAction::Stop(crate::Termination::ExceededMaxIterations);
39 }
40
41 EngineAction::Continue
42 }
43}
44
45#[cfg(test)]
46mod test {
47 use super::*;
48
49 use crate::engine::policy::PolicyStack;
50 use crate::progress::Progress;
51
52 #[test]
53 fn max_iteration_policy_terminates_when_iter_exceeds_limit() {
54 let mut stack = PolicyStack::<f64>::new().add(MaxIterationPolicy::new(100));
55
56 let batch: EventBatch<f64> = EventBatch::new().add(Progress::Complete);
57 let ctx = EngineContext {
58 iter: 101,
59 ..Default::default()
60 };
61
62 assert!(matches!(
63 stack.decide(&batch, &ctx),
64 EngineAction::Stop(crate::Termination::ExceededMaxIterations)
65 ))
66 }
67
68 #[test]
69 fn max_iteration_policy_does_not_terminate_when_iter_is_less_than_limit() {
70 let mut stack = PolicyStack::<f64>::new().add(MaxIterationPolicy::new(100));
71
72 let batch: EventBatch<f64> = EventBatch::new().add(Progress::Complete);
73 let ctx = EngineContext {
74 iter: 99,
75 ..Default::default()
76 };
77
78 assert!(matches!(stack.decide(&batch, &ctx), EngineAction::Continue))
79 }
80}