gol_core/board_states/
sparse.rs

1use crate::{BoardStateManager, IndexedDataOwned};
2use rayon::prelude::*;
3use std::collections::HashMap;
4
5pub struct SparseStates<T, CI> {
6    default_state: T,
7    lookup: HashMap<CI, T>,
8}
9
10impl<T, CI> SparseStates<T, CI> {
11    pub fn new(default_state: T, initial_states: HashMap<CI, T>) -> Self
12    where
13        CI: Eq + std::hash::Hash + Clone,
14        T: PartialEq + Clone,
15    {
16        Self {
17            default_state,
18            lookup: initial_states,
19        }
20    }
21}
22
23impl<T, CI> BoardStateManager<T, CI, rayon::vec::IntoIter<IndexedDataOwned<CI, T>>>
24    for SparseStates<T, CI>
25where
26    T: Send + Sync + Clone + PartialEq,
27    CI: Send + Sync + std::hash::Hash + Eq + Clone,
28{
29    fn get_cell_state(&self, idx: &CI) -> T {
30        match self.lookup.get(idx) {
31            Some(val) => val.clone(),
32            None => self.default_state.clone(),
33        }
34    }
35
36    fn update_cell_states_from_par_iter(
37        &mut self,
38        new_states: rayon::vec::IntoIter<IndexedDataOwned<CI, T>>,
39    ) {
40        self.lookup = new_states
41            .filter(|ele| ele.1 != self.default_state)
42            .map(|ele| (ele.0.clone(), ele.1.clone()))
43            .collect();
44    }
45}
46
47#[cfg(test)]
48mod sparse_state_manager_test {
49    use crate::{BoardStateManager, GridPoint2D, SparseStates};
50    use std::collections::HashMap;
51
52    #[test]
53    fn sparse_state_test_1() {
54        let mut initial_maps = HashMap::new();
55        initial_maps.insert(GridPoint2D { x: 0, y: 0 }, 1u8);
56        let states = SparseStates::new(0, initial_maps);
57        assert_eq!(states.get_cell_state(&GridPoint2D { x: 0, y: 0 }), 1);
58        assert_eq!(states.get_cell_state(&GridPoint2D { x: 1, y: 0 }), 0);
59        assert_eq!(states.get_cell_state(&GridPoint2D { x: 1, y: -5 }), 0);
60    }
61}