fuchsia_inspect/writer/types/
double_linear_histogram.rs1use crate::writer::{
6 ArithmeticArrayProperty, ArrayProperty, DoubleArrayProperty, HistogramProperty, InspectType,
7 Node,
8};
9use diagnostics_hierarchy::{ArrayFormat, LinearHistogramParams};
10use log::error;
11use std::borrow::Cow;
12
13#[derive(Debug, Default)]
14pub struct DoubleLinearHistogramProperty {
16 array: DoubleArrayProperty,
17 floor: f64,
18 buckets: usize,
19 step_size: f64,
20}
21
22impl InspectType for DoubleLinearHistogramProperty {}
23
24impl DoubleLinearHistogramProperty {
25 pub(crate) fn new(
26 name: Cow<'_, str>,
27 params: LinearHistogramParams<f64>,
28 parent: &Node,
29 ) -> Self {
30 let slots = params.buckets + ArrayFormat::LinearHistogram.extra_slots();
31 let array = parent.create_double_array_internal(name, slots, ArrayFormat::LinearHistogram);
32 array.set(0, params.floor);
33 array.set(1, params.step_size);
34 Self { floor: params.floor, step_size: params.step_size, buckets: params.buckets, array }
35 }
36
37 fn get_index(&self, value: f64) -> usize {
38 let mut bucket_end = self.floor; let mut index = ArrayFormat::LinearHistogram.underflow_bucket_index();
40 let overflow_index = ArrayFormat::LinearHistogram.overflow_bucket_index(self.buckets);
41 while value >= bucket_end && index < overflow_index {
42 bucket_end += self.step_size;
43 index += 1;
44 }
45 index
46 }
47}
48
49impl HistogramProperty for DoubleLinearHistogramProperty {
50 type Type = f64;
51
52 fn insert(&self, value: f64) {
53 self.insert_multiple(value, 1);
54 }
55
56 fn insert_multiple(&self, value: f64, count: usize) {
57 self.array.add(self.get_index(value), count as f64);
58 }
59
60 fn clear(&self) {
61 if let Some(ref inner_ref) = self.array.inner.inner_ref() {
62 inner_ref
64 .state
65 .try_lock()
66 .and_then(|mut state| {
67 state.clear_array(
70 inner_ref.block_index,
71 ArrayFormat::LinearHistogram.underflow_bucket_index(),
72 )
73 })
74 .unwrap_or_else(|err| {
75 error!(err:?; "Failed to clear property");
76 });
77 }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84 use crate::writer::Inspector;
85 use crate::writer::testing_utils::GetBlockExt;
86 use inspect_format::{Array, Double};
87
88 #[fuchsia::test]
89 fn double_linear_histogram() {
90 let inspector = Inspector::default();
91 let root = inspector.root();
92 let node = root.create_child("node");
93 {
94 let double_histogram = node.create_double_linear_histogram(
95 "double-histogram",
96 LinearHistogramParams { floor: 10.0, step_size: 5.0, buckets: 5 },
97 );
98 double_histogram.insert_multiple(0.0, 2); double_histogram.insert(25.3);
100 double_histogram.insert(500.0); double_histogram.array.get_block::<_, Array<Double>>(|block| {
102 for (i, value) in [10.0, 5.0, 2.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0].iter().enumerate()
103 {
104 assert_eq!(block.get(i).unwrap(), *value);
105 }
106 });
107
108 node.get_block::<_, inspect_format::Node>(|node_block| {
109 assert_eq!(node_block.child_count(), 1);
110 });
111 }
112 node.get_block::<_, inspect_format::Node>(|node_block| {
113 assert_eq!(node_block.child_count(), 0);
114 });
115 }
116}