pbrt_r3/core/stats/
stat_counter.rs

1#[cfg(feature = "stats")]
2mod _impl {
3
4    use super::super::stat_reporter::*;
5    use super::super::stats_accumlator::StatsAccumulator;
6    use crate::core::options::PbrtOptions;
7
8    use std::sync::Arc;
9    use std::sync::RwLock;
10
11    #[derive(Debug, Clone)]
12    struct BaseCountReporter {
13        pub name: String,
14        pub value: u64,
15    }
16
17    impl BaseCountReporter {
18        pub fn new(name: &str) -> Self {
19            BaseCountReporter {
20                name: name.to_string(),
21                value: 0,
22            }
23        }
24        pub fn add(&mut self, val: u64) {
25            self.value += val;
26        }
27    }
28
29    #[derive(Debug, Clone)]
30    struct CountReporter(BaseCountReporter);
31    impl CountReporter {
32        pub fn new(name: &str) -> Self {
33            CountReporter(BaseCountReporter::new(name))
34        }
35        fn add(&mut self, val: u64) {
36            self.0.add(val);
37        }
38    }
39    impl StatReporter for CountReporter {
40        fn report(&self, accum: &mut StatsAccumulator) {
41            accum.report_counter(&self.0.name, self.0.value);
42        }
43        fn clear(&mut self) {
44            self.0.value = 0;
45        }
46    }
47
48    #[derive(Debug, Clone)]
49    struct MemoryReporter(BaseCountReporter);
50    impl MemoryReporter {
51        pub fn new(name: &str) -> Self {
52            MemoryReporter(BaseCountReporter::new(name))
53        }
54        fn add(&mut self, val: u64) {
55            self.0.add(val);
56        }
57    }
58    impl StatReporter for MemoryReporter {
59        fn report(&self, accum: &mut StatsAccumulator) {
60            accum.report_memory_counter(&self.0.name, self.0.value);
61        }
62        fn clear(&mut self) {
63            self.0.value = 0;
64        }
65    }
66
67    #[derive(Debug, Clone)]
68    pub struct IntDistributionReporter {
69        pub name: String,
70        pub sum: u64,
71        pub count: u64,
72        pub min: u64,
73        pub max: u64,
74    }
75
76    impl IntDistributionReporter {
77        pub fn new(name: &str) -> Self {
78            IntDistributionReporter {
79                name: name.to_string(),
80                sum: 0,
81                count: 0,
82                min: std::u64::MAX,
83                max: std::u64::MIN,
84            }
85        }
86
87        pub fn add(&mut self, val: u64) {
88            self.sum += val;
89            self.count += 1;
90            self.min = self.min.min(val);
91            self.max = self.max.max(val);
92        }
93    }
94
95    impl StatReporter for IntDistributionReporter {
96        fn report(&self, accum: &mut StatsAccumulator) {
97            accum.report_int_distribution(&self.name, self.sum, self.count, self.min, self.max);
98        }
99        fn clear(&mut self) {
100            self.sum = 0;
101            self.count = 0;
102            self.min = std::u64::MAX;
103            self.max = std::u64::MIN;
104        }
105    }
106
107    #[derive(Debug, Clone)]
108    pub struct FloatDistributionReporter {
109        pub name: String,
110        pub sum: f64,
111        pub count: u64,
112        pub min: f64,
113        pub max: f64,
114    }
115
116    impl FloatDistributionReporter {
117        pub fn new(name: &str) -> Self {
118            FloatDistributionReporter {
119                name: name.to_string(),
120                sum: 0.0,
121                count: 0,
122                min: std::f64::MAX,
123                max: std::f64::MIN,
124            }
125        }
126
127        pub fn add(&mut self, val: f64) {
128            self.sum += val;
129            self.count += 1;
130            self.min = self.min.min(val);
131            self.max = self.max.max(val);
132        }
133    }
134
135    impl StatReporter for FloatDistributionReporter {
136        fn report(&self, accum: &mut StatsAccumulator) {
137            accum.report_float_distribution(&self.name, self.sum);
138        }
139        fn clear(&mut self) {
140            self.sum = 0.0;
141            self.count = 0;
142            self.min = std::f64::MAX;
143            self.max = std::f64::MIN;
144        }
145    }
146
147    #[derive(Debug, Clone)]
148    pub struct BaseFractionReporter {
149        pub name: String,
150        pub num: u64,
151        pub denom: u64,
152    }
153
154    impl BaseFractionReporter {
155        pub fn new(name: &str) -> Self {
156            BaseFractionReporter {
157                name: name.to_string(),
158                num: 0,
159                denom: 0,
160            }
161        }
162        fn clear(&mut self) {
163            self.num = 0;
164            self.denom = 0;
165        }
166        pub fn add_num(&mut self, val: u64) {
167            self.num += val;
168        }
169        pub fn add_denom(&mut self, val: u64) {
170            self.denom += val;
171        }
172    }
173
174    #[derive(Debug, Clone)]
175    struct PercentageReporter(BaseFractionReporter);
176
177    impl PercentageReporter {
178        pub fn new(name: &str) -> Self {
179            PercentageReporter(BaseFractionReporter::new(name))
180        }
181        fn add_num(&mut self, val: u64) {
182            self.0.add_num(val);
183        }
184        fn add_denom(&mut self, val: u64) {
185            self.0.add_denom(val);
186        }
187    }
188
189    impl StatReporter for PercentageReporter {
190        fn report(&self, accum: &mut StatsAccumulator) {
191            accum.report_percentage(&self.0.name, self.0.num, self.0.denom);
192        }
193        fn clear(&mut self) {
194            self.0.clear();
195        }
196    }
197
198    #[derive(Debug, Clone)]
199    struct RatioReporter(BaseFractionReporter);
200
201    impl RatioReporter {
202        pub fn new(name: &str) -> Self {
203            RatioReporter(BaseFractionReporter::new(name))
204        }
205        fn add_num(&mut self, val: u64) {
206            self.0.add_num(val);
207        }
208        fn add_denom(&mut self, val: u64) {
209            self.0.add_denom(val);
210        }
211    }
212
213    impl StatReporter for RatioReporter {
214        fn report(&self, accum: &mut StatsAccumulator) {
215            accum.report_percentage(&self.0.name, self.0.num, self.0.denom);
216        }
217        fn clear(&mut self) {
218            self.0.clear();
219        }
220    }
221
222    //-----------------------------------------------------------------------
223
224    pub struct StatCounter {
225        reporter: Arc<RwLock<CountReporter>>,
226        is_enabled: bool,
227    }
228
229    impl StatCounter {
230        pub fn new(name: &str) -> Self {
231            let reporter: Arc<RwLock<CountReporter>> =
232                Arc::new(RwLock::new(CountReporter::new(name)));
233            register_stat_reporter(reporter.clone());
234            let options = PbrtOptions::get();
235            let is_enabled = options.stats;
236            StatCounter {
237                reporter,
238                is_enabled,
239            }
240        }
241        pub fn inc(&self) {
242            self.add(1);
243        }
244        pub fn add(&self, val: u64) {
245            if !self.is_enabled {
246                return;
247            }
248            let mut reporter = self.reporter.write().unwrap();
249            reporter.add(val);
250        }
251    }
252
253    pub struct StatMemoryCounter {
254        reporter: Arc<RwLock<MemoryReporter>>,
255        is_enabled: bool,
256    }
257
258    impl StatMemoryCounter {
259        pub fn new(name: &str) -> Self {
260            let reporter: Arc<RwLock<MemoryReporter>> =
261                Arc::new(RwLock::new(MemoryReporter::new(name)));
262            register_stat_reporter(reporter.clone());
263            let options = PbrtOptions::get();
264            let is_enabled = options.stats;
265            StatMemoryCounter {
266                reporter,
267                is_enabled,
268            }
269        }
270        pub fn inc(&self) {
271            self.add(1);
272        }
273        pub fn add(&self, val: usize) {
274            if !self.is_enabled {
275                return;
276            }
277            let mut reporter = self.reporter.write().unwrap();
278            reporter.add(val as u64);
279        }
280    }
281
282    pub struct StatIntDistribution {
283        reporter: Arc<RwLock<IntDistributionReporter>>,
284        is_enabled: bool,
285    }
286
287    impl StatIntDistribution {
288        pub fn new(name: &str) -> Self {
289            let reporter: Arc<RwLock<IntDistributionReporter>> =
290                Arc::new(RwLock::new(IntDistributionReporter::new(name)));
291            register_stat_reporter(reporter.clone());
292            let options = PbrtOptions::get();
293            let is_enabled = options.stats;
294            StatIntDistribution {
295                reporter,
296                is_enabled,
297            }
298        }
299        pub fn add(&self, val: u64) {
300            if !self.is_enabled {
301                return;
302            }
303            let mut reporter = self.reporter.write().unwrap();
304            reporter.add(val);
305        }
306    }
307
308    pub struct StatFloatDistribution {
309        reporter: Arc<RwLock<FloatDistributionReporter>>,
310        is_enabled: bool,
311    }
312
313    impl StatFloatDistribution {
314        pub fn new(name: &str) -> Self {
315            let reporter: Arc<RwLock<FloatDistributionReporter>> =
316                Arc::new(RwLock::new(FloatDistributionReporter::new(name)));
317            register_stat_reporter(reporter.clone());
318            let options = PbrtOptions::get();
319            let is_enabled = options.stats;
320            StatFloatDistribution {
321                reporter,
322                is_enabled,
323            }
324        }
325        pub fn add(&self, val: f64) {
326            if !self.is_enabled {
327                return;
328            }
329            let mut reporter = self.reporter.write().unwrap();
330            reporter.add(val);
331        }
332    }
333
334    pub struct StatPercent {
335        reporter: Arc<RwLock<PercentageReporter>>,
336        is_enabled: bool,
337    }
338
339    impl StatPercent {
340        pub fn new(name: &str) -> Self {
341            let reporter: Arc<RwLock<PercentageReporter>> =
342                Arc::new(RwLock::new(PercentageReporter::new(name)));
343            register_stat_reporter(reporter.clone());
344            let options = PbrtOptions::get();
345            let is_enabled = options.stats;
346            StatPercent {
347                reporter,
348                is_enabled,
349            }
350        }
351        pub fn add_num(&self, val: u64) {
352            if !self.is_enabled {
353                return;
354            }
355            let mut reporter = self.reporter.write().unwrap();
356            reporter.add_num(val);
357        }
358        pub fn add_denom(&self, val: u64) {
359            if !self.is_enabled {
360                return;
361            }
362            let mut reporter = self.reporter.write().unwrap();
363            reporter.add_denom(val);
364        }
365    }
366
367    pub struct StatRatio {
368        reporter: Arc<RwLock<RatioReporter>>,
369        is_enabled: bool,
370    }
371
372    impl StatRatio {
373        pub fn new(name: &str) -> Self {
374            let reporter: Arc<RwLock<RatioReporter>> =
375                Arc::new(RwLock::new(RatioReporter::new(name)));
376            register_stat_reporter(reporter.clone());
377            let options = PbrtOptions::get();
378            let is_enabled = options.stats;
379            StatRatio {
380                reporter,
381                is_enabled,
382            }
383        }
384        pub fn add_num(&self, val: u64) {
385            if !self.is_enabled {
386                return;
387            }
388            let mut reporter = self.reporter.write().unwrap();
389            reporter.add_num(val);
390        }
391        pub fn add_denom(&self, val: u64) {
392            if !self.is_enabled {
393                return;
394            }
395            let mut reporter = self.reporter.write().unwrap();
396            reporter.add_denom(val);
397        }
398    }
399}
400
401#[cfg(not(feature = "stats"))]
402mod _impl {
403    pub struct StatCounter {}
404    impl StatCounter {
405        pub fn new(_name: &str) -> Self {
406            StatCounter {}
407        }
408        pub fn inc(&self) {}
409        pub fn add(&self, _val: u64) {}
410    }
411
412    pub struct StatMemoryCounter {}
413    impl StatMemoryCounter {
414        pub fn new(_name: &str) -> Self {
415            StatMemoryCounter {}
416        }
417        pub fn inc(&self) {}
418        pub fn add(&self, _val: usize) {}
419    }
420
421    pub struct StatIntDistribution {}
422    impl StatIntDistribution {
423        pub fn new(_name: &str) -> Self {
424            StatIntDistribution {}
425        }
426        pub fn add(&self, _val: u64) {}
427    }
428
429    pub struct StatFloatDistribution {}
430    impl StatFloatDistribution {
431        pub fn new(_name: &str) -> Self {
432            StatFloatDistribution {}
433        }
434        pub fn add(&self, _val: f64) {}
435    }
436
437    pub struct StatPercent {}
438    impl StatPercent {
439        pub fn new(_name: &str) -> Self {
440            StatPercent {}
441        }
442        pub fn add_num(&self, _val: u64) {}
443        pub fn add_denom(&self, _val: u64) {}
444    }
445
446    pub struct StatRatio {}
447    impl StatRatio {
448        pub fn new(_name: &str) -> Self {
449            StatRatio {}
450        }
451        pub fn add_num(&self, _val: u64) {}
452        pub fn add_denom(&self, _val: u64) {}
453    }
454}
455
456pub use _impl::*;