cecile_supercool_tracker/trackers/
tracker_api.rs

1use crate::store::TrackStore;
2use crate::track::notify::ChangeNotifier;
3use crate::track::TrackStatus;
4use crate::track::{ObservationAttributes, ObservationMetric, Track, TrackAttributes};
5use crate::trackers::epoch_db::EpochDb;
6use crate::trackers::sort::AutoWaste;
7use std::sync::{RwLockReadGuard, RwLockWriteGuard};
8
9pub trait TrackerAPI<TA, M, OA, E, N>
10where
11    TA: TrackAttributes<TA, OA>,
12    M: ObservationMetric<TA, OA>,
13    OA: ObservationAttributes,
14    N: ChangeNotifier,
15    E: EpochDb,
16{
17    fn get_auto_waste_obj_mut(&mut self) -> &mut AutoWaste;
18    fn get_opts(&self) -> &E;
19    fn get_main_store_mut(&mut self) -> RwLockWriteGuard<TrackStore<TA, M, OA, N>>;
20    fn get_wasted_store_mut(&mut self) -> RwLockWriteGuard<TrackStore<TA, M, OA, N>>;
21
22    fn get_main_store(&self) -> RwLockReadGuard<TrackStore<TA, M, OA, N>>;
23    fn get_wasted_store(&self) -> RwLockReadGuard<TrackStore<TA, M, OA, N>>;
24
25    /// change auto waste job periodicity
26    ///
27    fn set_auto_waste(&mut self, periodicity: usize) {
28        let obj = self.get_auto_waste_obj_mut();
29        obj.periodicity = periodicity;
30        obj.counter = 0;
31    }
32
33    /// Skip number of epochs to force tracks to turn to terminal state
34    ///
35    /// # Parameters
36    /// * `n` - number of epochs to skip for `scene_id` == 0
37    ///
38    fn skip_epochs(&mut self, n: usize) {
39        self.skip_epochs_for_scene(0, n)
40    }
41
42    /// Skip number of epochs to force tracks to turn to terminal state
43    ///
44    /// # Parameters
45    /// * `n` - number of epochs to skip for `scene_id`
46    /// * `scene_id` - scene to skip epochs
47    ///
48    fn skip_epochs_for_scene(&mut self, scene_id: u64, n: usize) {
49        self.get_opts().skip_epochs_for_scene(scene_id, n);
50        self.auto_waste();
51    }
52
53    /// Get the current epoch for `scene_id` == 0
54    ///
55    fn current_epoch(&self) -> usize {
56        self.current_epoch_with_scene(0)
57    }
58
59    /// Get the current epoch for `scene_id`
60    ///
61    /// # Parameters
62    /// * `scene_id` - scene id
63    ///
64    fn current_epoch_with_scene(&self, scene_id: u64) -> usize {
65        self.get_opts().current_epoch_with_scene(scene_id).unwrap()
66    }
67
68    /// Receive all the tracks with expired life from the main store
69    ///
70    fn get_main_store_wasted(&mut self) -> Vec<Track<TA, M, OA, N>> {
71        let tracks = self.get_main_store_mut().find_usable();
72        let wasted = tracks
73            .into_iter()
74            .filter(|(_, status)| matches!(status, Ok(TrackStatus::Wasted)))
75            .map(|(track, _)| track)
76            .collect::<Vec<_>>();
77
78        self.get_main_store_mut().fetch_tracks(&wasted)
79    }
80
81    fn auto_waste(&mut self) {
82        let tracks = self.get_main_store_wasted();
83        for t in tracks {
84            self.get_wasted_store_mut()
85                .add_track(t)
86                .expect("Cannot be a error, copying track to wasted store");
87        }
88    }
89
90    fn wasted(&mut self) -> Vec<Track<TA, M, OA, N>> {
91        self.auto_waste();
92        let tracks = self.get_wasted_store_mut().find_usable();
93        let wasted = tracks
94            .into_iter()
95            .filter(|(_, status)| matches!(status, Ok(TrackStatus::Wasted)))
96            .map(|(track, _)| track)
97            .collect::<Vec<_>>();
98
99        self.get_wasted_store_mut().fetch_tracks(&wasted)
100    }
101
102    /// Get the amount of tracks kept in main store per shard
103    ///
104    fn active_shard_stats(&self) -> Vec<usize> {
105        self.get_main_store().shard_stats()
106    }
107
108    /// Get the amount of tracks kept in wasted store per shard
109    ///
110    fn wasted_shard_stats(&self) -> Vec<usize> {
111        self.get_main_store().shard_stats()
112    }
113
114    /// Clears wasted tracks
115    fn clear_wasted(&self) {
116        self.get_wasted_store().clear();
117    }
118}