Skip to content

Commit e5d3549

Browse files
committed
Init aggregation data utils
1 parent a1dda22 commit e5d3549

File tree

7 files changed

+227
-230
lines changed

7 files changed

+227
-230
lines changed

opentelemetry-sdk/src/metrics/internal/aggregate.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{
22
marker,
33
mem::replace,
4-
ops::DerefMut,
4+
ops::{Deref, DerefMut},
55
sync::{Arc, Mutex},
66
time::SystemTime,
77
};
@@ -121,6 +121,65 @@ impl AttributeSetFilter {
121121
}
122122
}
123123

124+
pub(crate) trait InitAggregationData {
125+
type Aggr;
126+
fn create_new(&self, time: AggregateTime) -> Self::Aggr;
127+
fn reset_existing(&self, existing: &mut Self::Aggr, time: AggregateTime);
128+
}
129+
130+
pub(crate) enum AggregationData<'a, Aggr> {
131+
Existing(&'a mut Aggr),
132+
New(Aggr),
133+
}
134+
135+
impl<'a, Aggr> AggregationData<'a, Aggr>
136+
where
137+
Aggr: Aggregation,
138+
{
139+
pub(crate) fn init(
140+
init: &impl InitAggregationData<Aggr = Aggr>,
141+
existing: Option<&'a mut dyn Aggregation>,
142+
time: AggregateTime,
143+
) -> Self {
144+
match existing.and_then(|aggr| aggr.as_mut().downcast_mut::<Aggr>()) {
145+
Some(existing) => {
146+
init.reset_existing(existing, time);
147+
AggregationData::Existing(existing)
148+
}
149+
None => AggregationData::New(init.create_new(time)),
150+
}
151+
}
152+
153+
pub(crate) fn into_new_boxed(self) -> Option<Box<dyn Aggregation>> {
154+
match self {
155+
AggregationData::Existing(_) => None,
156+
AggregationData::New(aggregation) => {
157+
Some(Box::new(aggregation) as Box<dyn Aggregation>)
158+
}
159+
}
160+
}
161+
}
162+
163+
impl<Aggr> Deref for AggregationData<'_, Aggr> {
164+
type Target = Aggr;
165+
166+
fn deref(&self) -> &Self::Target {
167+
match self {
168+
AggregationData::Existing(existing) => existing,
169+
AggregationData::New(new) => new,
170+
}
171+
}
172+
}
173+
174+
impl<Aggr> DerefMut for AggregationData<'_, Aggr> {
175+
fn deref_mut(&mut self) -> &mut Self::Target {
176+
match self {
177+
AggregationData::Existing(existing) => existing,
178+
AggregationData::New(new) => new,
179+
}
180+
}
181+
}
182+
124183
/// Builds aggregate functions
125184
pub(crate) struct AggregateBuilder<T> {
126185
/// The temporality used for the returned aggregate functions.

opentelemetry-sdk/src/metrics/internal/exponential_histogram.rs

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ use crate::metrics::{
99
};
1010

1111
use super::{
12-
aggregate::{AggregateTimeInitiator, AttributeSetFilter},
12+
aggregate::{
13+
AggregateTime, AggregateTimeInitiator, AggregationData, AttributeSetFilter,
14+
InitAggregationData,
15+
},
1316
Aggregator, ComputeAggregation, Measure, Number, ValueMap,
1417
};
1518

@@ -384,26 +387,10 @@ impl<T: Number> ExpoHistogram<T> {
384387
}
385388

386389
fn delta(&self, dest: Option<&mut dyn Aggregation>) -> (usize, Option<Box<dyn Aggregation>>) {
387-
let time = self.init_time.delta();
388-
389-
let h = dest.and_then(|d| d.as_mut().downcast_mut::<data::ExponentialHistogram<T>>());
390-
let mut new_agg = if h.is_none() {
391-
Some(data::ExponentialHistogram {
392-
data_points: vec![],
393-
start_time: time.start,
394-
time: time.current,
395-
temporality: Temporality::Delta,
396-
})
397-
} else {
398-
None
399-
};
400-
let h = h.unwrap_or_else(|| new_agg.as_mut().expect("present if h is none"));
401-
h.temporality = Temporality::Delta;
402-
h.start_time = time.start;
403-
h.time = time.current;
390+
let mut s_data = AggregationData::init(self, dest, self.init_time.delta());
404391

405392
self.value_map
406-
.collect_and_reset(&mut h.data_points, |attributes, attr| {
393+
.collect_and_reset(&mut s_data.data_points, |attributes, attr| {
407394
let b = attr.into_inner().unwrap_or_else(|err| err.into_inner());
408395
data::ExponentialHistogramDataPoint {
409396
attributes,
@@ -434,33 +421,17 @@ impl<T: Number> ExpoHistogram<T> {
434421
}
435422
});
436423

437-
(h.data_points.len(), new_agg.map(|a| Box::new(a) as Box<_>))
424+
(s_data.data_points.len(), s_data.into_new_boxed())
438425
}
439426

440427
fn cumulative(
441428
&self,
442429
dest: Option<&mut dyn Aggregation>,
443430
) -> (usize, Option<Box<dyn Aggregation>>) {
444-
let time = self.init_time.cumulative();
445-
446-
let h = dest.and_then(|d| d.as_mut().downcast_mut::<data::ExponentialHistogram<T>>());
447-
let mut new_agg = if h.is_none() {
448-
Some(data::ExponentialHistogram {
449-
data_points: vec![],
450-
start_time: time.start,
451-
time: time.current,
452-
temporality: Temporality::Cumulative,
453-
})
454-
} else {
455-
None
456-
};
457-
let h = h.unwrap_or_else(|| new_agg.as_mut().expect("present if h is none"));
458-
h.temporality = Temporality::Cumulative;
459-
h.start_time = time.start;
460-
h.time = time.current;
431+
let mut s_data = AggregationData::init(self, dest, self.init_time.cumulative());
461432

462433
self.value_map
463-
.collect_readonly(&mut h.data_points, |attributes, attr| {
434+
.collect_readonly(&mut s_data.data_points, |attributes, attr| {
464435
let b = attr.lock().unwrap_or_else(|err| err.into_inner());
465436
data::ExponentialHistogramDataPoint {
466437
attributes,
@@ -491,7 +462,7 @@ impl<T: Number> ExpoHistogram<T> {
491462
}
492463
});
493464

494-
(h.data_points.len(), new_agg.map(|a| Box::new(a) as Box<_>))
465+
(s_data.data_points.len(), s_data.into_new_boxed())
495466
}
496467
}
497468

@@ -524,6 +495,30 @@ where
524495
}
525496
}
526497
}
498+
499+
impl<T> InitAggregationData for ExpoHistogram<T>
500+
where
501+
T: Number,
502+
{
503+
type Aggr = data::ExponentialHistogram<T>;
504+
505+
fn create_new(&self, time: AggregateTime) -> Self::Aggr {
506+
data::ExponentialHistogram {
507+
data_points: vec![],
508+
start_time: time.start,
509+
time: time.current,
510+
temporality: self.temporality,
511+
}
512+
}
513+
514+
fn reset_existing(&self, existing: &mut Self::Aggr, time: AggregateTime) {
515+
existing.data_points.clear();
516+
existing.start_time = time.start;
517+
existing.time = time.current;
518+
existing.temporality = self.temporality;
519+
}
520+
}
521+
527522
#[cfg(test)]
528523
mod tests {
529524
use std::{ops::Neg, time::SystemTime};

opentelemetry-sdk/src/metrics/internal/histogram.rs

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ use crate::metrics::data::{self, Aggregation};
77
use crate::metrics::Temporality;
88
use opentelemetry::KeyValue;
99

10-
use super::aggregate::AggregateTimeInitiator;
1110
use super::aggregate::AttributeSetFilter;
11+
use super::aggregate::{
12+
AggregateTime, AggregateTimeInitiator, AggregationData, InitAggregationData,
13+
};
1214
use super::ComputeAggregation;
1315
use super::Measure;
1416
use super::ValueMap;
@@ -108,26 +110,10 @@ impl<T: Number> Histogram<T> {
108110
}
109111

110112
fn delta(&self, dest: Option<&mut dyn Aggregation>) -> (usize, Option<Box<dyn Aggregation>>) {
111-
let time = self.init_time.delta();
112-
113-
let h = dest.and_then(|d| d.as_mut().downcast_mut::<data::Histogram<T>>());
114-
let mut new_agg = if h.is_none() {
115-
Some(data::Histogram {
116-
data_points: vec![],
117-
start_time: time.start,
118-
time: time.current,
119-
temporality: Temporality::Delta,
120-
})
121-
} else {
122-
None
123-
};
124-
let h = h.unwrap_or_else(|| new_agg.as_mut().expect("present if h is none"));
125-
h.temporality = Temporality::Delta;
126-
h.start_time = time.start;
127-
h.time = time.current;
113+
let mut s_data = AggregationData::init(self, dest, self.init_time.delta());
128114

129115
self.value_map
130-
.collect_and_reset(&mut h.data_points, |attributes, aggr| {
116+
.collect_and_reset(&mut s_data.data_points, |attributes, aggr| {
131117
let b = aggr.into_inner().unwrap_or_else(|err| err.into_inner());
132118
HistogramDataPoint {
133119
attributes,
@@ -153,32 +139,17 @@ impl<T: Number> Histogram<T> {
153139
}
154140
});
155141

156-
(h.data_points.len(), new_agg.map(|a| Box::new(a) as Box<_>))
142+
(s_data.data_points.len(), s_data.into_new_boxed())
157143
}
158144

159145
fn cumulative(
160146
&self,
161147
dest: Option<&mut dyn Aggregation>,
162148
) -> (usize, Option<Box<dyn Aggregation>>) {
163-
let time = self.init_time.cumulative();
164-
let h = dest.and_then(|d| d.as_mut().downcast_mut::<data::Histogram<T>>());
165-
let mut new_agg = if h.is_none() {
166-
Some(data::Histogram {
167-
data_points: vec![],
168-
start_time: time.start,
169-
time: time.current,
170-
temporality: Temporality::Cumulative,
171-
})
172-
} else {
173-
None
174-
};
175-
let h = h.unwrap_or_else(|| new_agg.as_mut().expect("present if h is none"));
176-
h.temporality = Temporality::Cumulative;
177-
h.start_time = time.start;
178-
h.time = time.current;
149+
let mut s_data = AggregationData::init(self, dest, self.init_time.cumulative());
179150

180151
self.value_map
181-
.collect_readonly(&mut h.data_points, |attributes, aggr| {
152+
.collect_readonly(&mut s_data.data_points, |attributes, aggr| {
182153
let b = aggr.lock().unwrap_or_else(|err| err.into_inner());
183154
HistogramDataPoint {
184155
attributes,
@@ -204,7 +175,7 @@ impl<T: Number> Histogram<T> {
204175
}
205176
});
206177

207-
(h.data_points.len(), new_agg.map(|a| Box::new(a) as Box<_>))
178+
(s_data.data_points.len(), s_data.into_new_boxed())
208179
}
209180
}
210181

@@ -239,6 +210,29 @@ where
239210
}
240211
}
241212

213+
impl<T> InitAggregationData for Histogram<T>
214+
where
215+
T: Number,
216+
{
217+
type Aggr = data::Histogram<T>;
218+
219+
fn create_new(&self, time: AggregateTime) -> Self::Aggr {
220+
data::Histogram {
221+
data_points: vec![],
222+
start_time: time.start,
223+
time: time.current,
224+
temporality: self.temporality,
225+
}
226+
}
227+
228+
fn reset_existing(&self, existing: &mut Self::Aggr, time: AggregateTime) {
229+
existing.data_points.clear();
230+
existing.start_time = time.start;
231+
existing.time = time.current;
232+
existing.temporality = self.temporality;
233+
}
234+
}
235+
242236
#[cfg(test)]
243237
mod tests {
244238
use super::*;

0 commit comments

Comments
 (0)