1use crate::candidate::Candidate;
2use crate::gas::cycle::CycleProgress;
3use crate::gas::Gas;
4use std::sync::atomic::AtomicBool;
5use std::sync::Arc;
6use std::thread;
7
8#[mockall_double::double]
9use crate::rando::Rando;
10pub struct Pool<const N: usize, const NSYMS: usize> {
17 pub progresses: Vec<CycleProgress<N, NSYMS>>,
18 pub handles: Vec<thread::JoinHandle<Candidate<N, NSYMS>>>,
19 pub sigint: Arc<AtomicBool>,
20}
21
22impl<const N: usize, const NSYMS: usize> Pool<N, NSYMS> {
23 pub fn new(
24 gas: Arc<Gas<N, NSYMS>>,
25 nthreads: usize,
26 sigint: Arc<AtomicBool>,
27 ) -> Pool<N, NSYMS> {
28 let mut progresses = Vec::<CycleProgress<N, NSYMS>>::with_capacity(nthreads);
29 let mut handles = Vec::<thread::JoinHandle<Candidate<N, NSYMS>>>::with_capacity(nthreads);
30
31 for _ in 0..nthreads {
32 let igas = gas.clone();
33 let mut progress = CycleProgress::new(&igas, &sigint);
34 progresses.push(progress.clone());
35
36 handles.push(thread::spawn(move || igas.cycle(&mut progress)));
37 }
38 Pool {
39 progresses,
40 handles,
41 sigint,
42 }
43 }
44
45 pub fn is_finished(&self) -> bool {
46 self.handles.iter().all(|h| h.is_finished())
47 }
48
49 pub fn winner(&mut self, gas: Arc<Gas<N, NSYMS>>) -> Candidate<N, NSYMS> {
50 let mut rng = Rando::new();
51 let winners: Vec<Candidate<N, NSYMS>> =
52 self.handles.drain(..).map(|h| h.join().unwrap()).collect();
53 let (winner, _) = gas
54 .final_tournament
55 .run(&winners, &mut rng, &gas.fitness.weights());
56 winner
57 }
58}