fuzzcheck/sensors_and_pools/
maximise_observation_pool.rs1use std::fmt::{Debug, Display};
2use std::path::PathBuf;
3
4use crate::traits::{CorpusDelta, Pool, SaveToStatsFolder, Stats};
5use crate::{CSVField, CompatibleWithObservations, PoolStorageIndex, ToCSV};
6
7#[derive(Clone, Copy, PartialEq, Eq, Hash)]
8struct Unit;
9
10struct Input {
11 input_id: PoolStorageIndex,
12 complexity: f64,
13}
14
15pub struct MaximiseObservationPool<T> {
17 name: String,
18 current_best: Option<(T, Input)>,
19}
20#[derive(Clone)]
21pub struct MaximiseObservationPoolStats<T> {
22 name: String,
23 best: T,
24}
25impl<T> Display for MaximiseObservationPoolStats<T>
26where
27 T: Debug,
28{
29 #[coverage(off)]
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 write!(f, "{}({:?})", self.name, self.best)
32 }
33}
34impl<T> ToCSV for MaximiseObservationPoolStats<T>
35where
36 T: Debug,
37{
38 #[coverage(off)]
39 fn csv_headers(&self) -> Vec<CSVField> {
40 vec![CSVField::String(self.name.clone())]
41 }
42 #[coverage(off)]
43 fn to_csv_record(&self) -> Vec<CSVField> {
44 vec![CSVField::String(format!("{:?}", self.best))]
45 }
46}
47impl<T> Stats for MaximiseObservationPoolStats<T> where T: Debug + Default + 'static {}
48
49impl<T> MaximiseObservationPool<T> {
50 #[coverage(off)]
51 pub fn new(name: &str) -> Self {
52 Self {
53 name: name.to_string(),
54 current_best: None,
55 }
56 }
57}
58impl<T> Pool for MaximiseObservationPool<T>
59where
60 T: Clone + Debug + Default + 'static,
61{
62 type Stats = MaximiseObservationPoolStats<T>;
63
64 #[coverage(off)]
65 fn stats(&self) -> Self::Stats {
66 MaximiseObservationPoolStats {
67 name: self.name.clone(),
68 best: self
69 .current_best
70 .as_ref()
71 .map(
72 #[coverage(off)]
73 |z| z.0.clone(),
74 )
75 .unwrap_or_default(),
76 }
77 }
78 #[coverage(off)]
79 fn get_random_index(&mut self) -> Option<PoolStorageIndex> {
80 if let Some(best) = &self.current_best {
81 Some(best.1.input_id)
82 } else {
83 None
84 }
85 }
86}
87impl<T> SaveToStatsFolder for MaximiseObservationPool<T> {
88 #[coverage(off)]
89 fn save_to_stats_folder(&self) -> Vec<(PathBuf, Vec<u8>)> {
90 vec![]
91 }
92}
93
94impl<T> CompatibleWithObservations<T> for MaximiseObservationPool<T>
95where
96 T: Clone + Debug + Default + PartialOrd + 'static,
97{
98 #[coverage(off)]
99 fn process(&mut self, input_id: PoolStorageIndex, observations: &T, complexity: f64) -> Vec<CorpusDelta> {
100 let observations = observations.clone();
101 let is_interesting = if let Some((counter, cur_input)) = &self.current_best {
102 observations > *counter || (observations == *counter && cur_input.complexity > complexity)
103 } else {
104 true
105 };
106 if !is_interesting {
107 return vec![];
108 }
109 let delta = CorpusDelta {
110 path: PathBuf::new().join(&self.name),
111 add: true,
112 remove: if let Some(best) = &self.current_best {
113 vec![best.1.input_id]
114 } else {
115 vec![]
116 },
117 };
118 let new = Input { input_id, complexity };
119 self.current_best = Some((observations, new));
120 vec![delta]
121 }
122}