pure_stage/simulation/
random.rs1use std::collections::VecDeque;
16
17use rand::{
18 Rng, SeedableRng,
19 distr::uniform::{SampleRange, SampleUniform},
20 rngs::StdRng,
21};
22
23use crate::{Name, StageResponse};
24
25pub trait EvalStrategy: Send + 'static {
31 fn pick_runnable(&mut self, runnable: &mut VecDeque<(Name, StageResponse)>) -> (Name, StageResponse);
33}
34
35pub struct Fifo;
36
37impl EvalStrategy for Fifo {
38 fn pick_runnable(&mut self, runnable: &mut VecDeque<(Name, StageResponse)>) -> (Name, StageResponse) {
39 runnable.pop_front().expect("runnable queue is guaranteed to be non-empty")
40 }
41}
42
43pub struct RandStdRng(pub StdRng);
44
45impl RandStdRng {
46 pub fn from_seed(seed: u64) -> Self {
47 RandStdRng(StdRng::seed_from_u64(seed))
48 }
49
50 pub fn derive(&mut self) -> Self {
51 RandStdRng(StdRng::seed_from_u64(self.0.random()))
52 }
53
54 pub fn random_range<T, R>(&mut self, range: R) -> T
55 where
56 T: SampleUniform,
57 R: SampleRange<T>,
58 {
59 self.0.random_range(range)
60 }
61}
62
63impl From<StdRng> for RandStdRng {
64 fn from(rng: StdRng) -> Self {
65 RandStdRng(rng)
66 }
67}
68
69impl EvalStrategy for RandStdRng {
70 fn pick_runnable(&mut self, runnable: &mut VecDeque<(Name, StageResponse)>) -> (Name, StageResponse) {
71 let idx = self.0.random_range(0..runnable.len());
72 runnable.remove(idx).expect("runnable queue is guaranteed to be non-empty")
73 }
74}
75
76impl EvalStrategy for Box<dyn EvalStrategy> {
77 fn pick_runnable(&mut self, runnable: &mut VecDeque<(Name, StageResponse)>) -> (Name, StageResponse) {
78 (**self).pick_runnable(runnable)
79 }
80}