metrics_procession/
procession.rs1use time::Duration;
2
3use metrics::{Key, Label};
4use serde::{Deserialize, Serialize};
5use time::OffsetDateTime;
6
7use crate::{
8 chunk::Chunk,
9 event::{Entry, Event},
10 iter::{Metric, MetricRef, MetricsIterator, MetricsRefIterator},
11 label_set::LabelSet,
12};
13
14#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Default)]
16pub struct Procession {
17 pub chunks: Vec<Chunk>,
19 pub labels: LabelSet,
21}
22
23impl Procession {
24 pub fn memory_size(&self) -> usize {
26 use std::{collections::HashSet, mem::size_of};
27 let mut shared_string_set = HashSet::new();
28 let labels_size = self
29 .labels
30 .0
31 .keys()
32 .map(|k| {
33 let k_size = if shared_string_set.insert(k.name()) {
34 k.name().len()
35 } else {
36 0
37 } + size_of::<Key>();
38 let l_size = k.labels().fold(0, |acc, l| {
39 let l_size = if shared_string_set.insert(l.key()) {
40 l.key().len()
41 } else {
42 0
43 } + size_of::<Label>();
44 let v_size = if shared_string_set.insert(l.value()) {
45 l.value().len()
46 } else {
47 0
48 } + size_of::<Label>();
49 acc + l_size + v_size
50 });
51 k_size + l_size + size_of::<u16>()
52 })
53 .sum::<usize>();
54 let chunk_size = self.chunks.iter().map(|c| c.memory_size()).sum::<usize>();
55 labels_size + chunk_size + size_of::<Self>()
56 }
57
58 pub fn insert_entry(&mut self, entry: Entry, label: u16) {
60 let now = OffsetDateTime::now_utc();
61 let (last, ms) = self.last_chunk_and_ms(now);
62 last.push(Event { entry, ms, label });
63 }
64
65 pub fn last_chunk_and_ms(&mut self, now: OffsetDateTime) -> (&mut Chunk, u16) {
71 if self.chunks.is_empty() {
72 self.chunks.push(Chunk::default());
73 }
74 let mut duration = self
75 .chunks
76 .last()
77 .map(|c| (now - c.reference_time))
78 .unwrap_or_default();
79 if duration > Duration::milliseconds(i64::from(u16::MAX)) {
80 self.chunks.push(Chunk::new(now));
81 duration = Duration::ZERO;
82 }
83 let ms = u16::try_from(duration.whole_milliseconds()).unwrap_or(u16::MAX);
84 (self.chunks.last_mut().unwrap(), ms)
85 }
86
87 pub fn ensure_label(&mut self, k: &Key) -> u16 {
89 self.labels.ensure_key(k)
90 }
91
92 pub fn iter(&self) -> MetricsRefIterator {
95 MetricsRefIterator::from(self)
96 }
97
98 pub fn iter_owned(&self) -> MetricsIterator {
101 self.iter().into()
102 }
103}
104
105impl FromIterator<Metric> for Procession {
106 fn from_iter<T: IntoIterator<Item = Metric>>(iter: T) -> Self {
107 let mut iter = iter.into_iter().peekable();
108 let mut ret = Self::default();
109 if let Some(first) = iter.peek() {
110 let start = first.when;
111 ret.chunks.push(Chunk::new(start));
112 }
113 for event in iter {
114 let labels = event
115 .labels
116 .into_iter()
117 .map(|(k, v)| Label::new(k, v))
118 .collect::<Vec<_>>();
119 let label = ret.ensure_label(&Key::from_parts(event.key, labels));
120 ret.insert_entry(event.event, label);
121 }
122 ret
123 }
124}
125
126impl<'a> FromIterator<MetricRef<'a>> for Procession {
127 fn from_iter<T: IntoIterator<Item = MetricRef<'a>>>(iter: T) -> Self {
128 let mut iter = iter.into_iter().peekable();
129 let mut ret = Self::default();
130 if let Some(first) = iter.peek() {
131 let start = first.when;
132 ret.chunks.push(Chunk::new(start));
133 }
134 for event in iter {
135 let label = ret.ensure_label(event.key);
136 ret.insert_entry(event.event, label);
137 }
138 ret
139 }
140}