1use std::any::Any;
2use std::cell::{Cell, RefCell};
3use std::hash::Hash;
4use std::marker::PhantomData;
5use std::rc::Rc;
6
7use crate::bloom_filter::BloomFilter;
8use crate::Mutator;
9
10const SIZE_BLOOM: usize = 10_000_000;
11const FALSE_POSITIVE_RATE: f64 = 0.000_001;
12
13pub struct UniqueMutator<T, TH, Focus, M>
18where
19 T: Clone + 'static,
20 TH: Hash,
21 M: Mutator<T>,
22 Focus: Fn(&T) -> &TH,
23{
24 mutator: M,
25 uniques: Rc<RefCell<BloomFilter<TH>>>,
26 nbr_inserted: Cell<usize>,
27 focus: Focus,
28 _phantom: PhantomData<T>,
29}
30
31impl<T, TH, Focus, M> UniqueMutator<T, TH, Focus, M>
32where
33 T: Clone + 'static,
34 TH: Hash,
35 M: Mutator<T>,
36 Focus: Fn(&T) -> &TH,
37{
38 #[coverage(off)]
46 pub fn new(mutator: M, focus: Focus) -> Self {
47 Self {
48 mutator,
49 uniques: Rc::new(RefCell::new(BloomFilter::new(SIZE_BLOOM, FALSE_POSITIVE_RATE))),
50 nbr_inserted: <_>::default(),
51 focus,
52 _phantom: <_>::default(),
53 }
54 }
55}
56impl<T, TH, Focus, M> UniqueMutator<T, TH, Focus, M>
57where
58 T: Clone + 'static,
59 TH: Hash,
60 M: Mutator<T>,
61 Focus: Fn(&T) -> &TH,
62 Self: 'static,
63{
64 #[coverage(off)]
65 fn clear_if_needed(&self) {
66 if self.nbr_inserted.get() >= SIZE_BLOOM {
67 let bitmap = &mut self.uniques.borrow_mut().bitmap;
68 bitmap.clear();
69 self.nbr_inserted.set(0);
70 }
71 }
72}
73impl<T, TH, Focus, M> Mutator<T> for UniqueMutator<T, TH, Focus, M>
74where
75 T: Clone + 'static,
76 TH: Hash,
77 M: Mutator<T>,
78 Focus: Fn(&T) -> &TH,
79 Self: 'static,
80{
81 type Cache = M::Cache;
82 type MutationStep = M::MutationStep;
83 type ArbitraryStep = M::ArbitraryStep;
84 type UnmutateToken = M::UnmutateToken;
85
86 #[coverage(off)]
87 fn initialize(&self) {
88 self.mutator.initialize();
89 }
90
91 #[coverage(off)]
92 fn default_arbitrary_step(&self) -> Self::ArbitraryStep {
93 self.mutator.default_arbitrary_step()
94 }
95
96 #[coverage(off)]
97 fn is_valid(&self, value: &T) -> bool {
98 self.mutator.is_valid(value)
99 }
100
101 #[coverage(off)]
102 fn validate_value(&self, value: &T) -> Option<Self::Cache> {
103 self.mutator.validate_value(value)
104 }
105 #[coverage(off)]
106 fn default_mutation_step(&self, value: &T, cache: &Self::Cache) -> Self::MutationStep {
107 self.mutator.default_mutation_step(value, cache)
108 }
109
110 #[doc(hidden)]
111 #[coverage(off)]
112 fn global_search_space_complexity(&self) -> f64 {
113 self.mutator.global_search_space_complexity()
114 }
115
116 #[coverage(off)]
117 fn max_complexity(&self) -> f64 {
118 self.mutator.max_complexity()
119 }
120
121 #[coverage(off)]
122 fn min_complexity(&self) -> f64 {
123 self.mutator.min_complexity()
124 }
125
126 #[coverage(off)]
127 fn complexity(&self, value: &T, cache: &Self::Cache) -> f64 {
128 self.mutator.complexity(value, cache)
129 }
130
131 #[coverage(off)]
132 fn ordered_arbitrary(&self, step: &mut Self::ArbitraryStep, max_cplx: f64) -> Option<(T, f64)> {
133 self.clear_if_needed();
134 loop {
135 if let Some((v, cplx)) = self.mutator.ordered_arbitrary(step, max_cplx) {
136 let mut uniques = self.uniques.borrow_mut();
137 let focused = (self.focus)(&v);
138 if uniques.contains(focused) {
139 drop(uniques);
140 } else {
141 uniques.insert(focused);
142 let prev_inserted = self.nbr_inserted.get();
143 self.nbr_inserted.set(prev_inserted + 1);
144 return Some((v, cplx));
145 }
146 } else {
147 return None;
148 }
149 }
150 }
151
152 #[coverage(off)]
153 fn random_arbitrary(&self, _max_cplx: f64) -> (T, f64) {
154 panic!()
155 }
156
157 #[coverage(off)]
158 fn ordered_mutate(
159 &self,
160 value: &mut T,
161 cache: &mut Self::Cache,
162 step: &mut Self::MutationStep,
163 subvalue_provider: &dyn crate::SubValueProvider,
164 max_cplx: f64,
165 ) -> Option<(Self::UnmutateToken, f64)> {
166 self.clear_if_needed();
167 loop {
168 if let Some((t, cplx)) = self
169 .mutator
170 .ordered_mutate(value, cache, step, subvalue_provider, max_cplx)
171 {
172 let mut uniques = self.uniques.borrow_mut();
173 let focused = (self.focus)(value);
174 if uniques.contains(focused) || cplx >= max_cplx {
175 drop(uniques);
176 self.unmutate(value, cache, t);
177 } else {
178 uniques.insert(focused);
179 let prev_inserted = self.nbr_inserted.get();
180 self.nbr_inserted.set(prev_inserted + 1);
181 return Some((t, cplx));
182 }
183 } else {
184 return None;
185 }
186 }
187 }
188
189 #[coverage(off)]
190 fn random_mutate(&self, value: &mut T, cache: &mut Self::Cache, max_cplx: f64) -> (Self::UnmutateToken, f64) {
191 self.clear_if_needed();
192 for _ in 0..20 {
193 let (t, cplx) = self.mutator.random_mutate(value, cache, max_cplx);
194 let mut uniques = self.uniques.borrow_mut();
195 let focused = (self.focus)(value);
196 if uniques.contains(focused) || cplx >= max_cplx {
197 drop(uniques);
198 self.unmutate(value, cache, t);
199 } else {
200 uniques.insert(focused);
201 let prev_inserted = self.nbr_inserted.get();
202 self.nbr_inserted.set(prev_inserted + 1);
203 return (t, cplx);
204 }
205 }
206 self.mutator.random_mutate(value, cache, max_cplx)
207 }
208
209 #[coverage(off)]
210 fn unmutate(&self, value: &mut T, cache: &mut Self::Cache, t: Self::UnmutateToken) {
211 self.mutator.unmutate(value, cache, t)
212 }
213
214 #[coverage(off)]
215 fn visit_subvalues<'a>(&self, value: &'a T, cache: &'a Self::Cache, visit: &mut dyn FnMut(&'a dyn Any, f64)) {
216 self.mutator.visit_subvalues(value, cache, visit)
217 }
218}