fxprof_processed_profile/
counters.rs1use serde::ser::{Serialize, SerializeMap, Serializer};
2
3use crate::{ProcessHandle, Timestamp};
4
5#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
7pub struct CounterHandle(pub(crate) usize);
8
9#[derive(Debug)]
10pub struct Counter {
11 name: String,
12 category: String,
13 description: String,
14 process: ProcessHandle,
15 pid: String,
16 samples: CounterSamples,
17}
18
19impl Counter {
20 pub fn new(
21 name: &str,
22 category: &str,
23 description: &str,
24 process: ProcessHandle,
25 pid: &str,
26 ) -> Self {
27 Counter {
28 name: name.to_owned(),
29 category: category.to_owned(),
30 description: description.to_owned(),
31 process,
32 pid: pid.to_owned(),
33 samples: CounterSamples::new(),
34 }
35 }
36
37 pub fn process(&self) -> ProcessHandle {
38 self.process
39 }
40
41 pub fn add_sample(
42 &mut self,
43 timestamp: Timestamp,
44 value_delta: f64,
45 number_of_operations_delta: u32,
46 ) {
47 self.samples
48 .add_sample(timestamp, value_delta, number_of_operations_delta)
49 }
50
51 pub fn as_serializable(&self, main_thread_index: usize) -> impl Serialize + '_ {
52 SerializableCounter {
53 counter: self,
54 main_thread_index,
55 }
56 }
57}
58
59struct SerializableCounter<'a> {
60 counter: &'a Counter,
61 main_thread_index: usize,
63}
64
65impl<'a> Serialize for SerializableCounter<'a> {
66 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
67 let mut map = serializer.serialize_map(None)?;
68 map.serialize_entry("category", &self.counter.category)?;
69 map.serialize_entry("name", &self.counter.name)?;
70 map.serialize_entry("description", &self.counter.description)?;
71 map.serialize_entry("mainThreadIndex", &self.main_thread_index)?;
72 map.serialize_entry("pid", &self.counter.pid)?;
73 map.serialize_entry(
74 "sampleGroups",
75 &[SerializableCounterSampleGroup(self.counter)],
76 )?;
77 map.end()
78 }
79}
80
81struct SerializableCounterSampleGroup<'a>(&'a Counter);
82
83impl<'a> Serialize for SerializableCounterSampleGroup<'a> {
84 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
85 let mut map = serializer.serialize_map(None)?;
86 map.serialize_entry("id", &0)?; map.serialize_entry("samples", &self.0.samples)?;
88 map.end()
89 }
90}
91
92#[derive(Debug)]
93struct CounterSamples {
94 time: Vec<Timestamp>,
95 number: Vec<u32>,
96 count: Vec<f64>,
97}
98
99impl CounterSamples {
100 pub fn new() -> Self {
101 Self {
102 time: Vec::new(),
103 number: Vec::new(),
104 count: Vec::new(),
105 }
106 }
107
108 pub fn add_sample(
109 &mut self,
110 timestamp: Timestamp,
111 value_delta: f64,
112 number_of_operations_delta: u32,
113 ) {
114 self.time.push(timestamp);
115 self.count.push(value_delta);
116 self.number.push(number_of_operations_delta);
117 }
118}
119
120impl Serialize for CounterSamples {
121 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
122 let len = self.time.len();
123 let mut map = serializer.serialize_map(None)?;
124 map.serialize_entry("length", &len)?;
125 map.serialize_entry("count", &self.count)?;
126 map.serialize_entry("number", &self.number)?;
127 map.serialize_entry("time", &self.time)?;
128 map.end()
129 }
130}