77
88import io .opentelemetry .api .common .Attributes ;
99import io .opentelemetry .context .Context ;
10- import io .opentelemetry .sdk .metrics .data .ExemplarData ;
10+ import io .opentelemetry .sdk .metrics .data .DoubleExemplarData ;
11+ import io .opentelemetry .sdk .metrics .data .LongExemplarData ;
1112import io .opentelemetry .sdk .metrics .data .PointData ;
12- import io .opentelemetry .sdk .metrics .internal .exemplar .ExemplarReservoir ;
13+ import io .opentelemetry .sdk .metrics .internal .exemplar .DoubleExemplarReservoir ;
14+ import io .opentelemetry .sdk .metrics .internal .exemplar .ExemplarReservoirFactory ;
15+ import io .opentelemetry .sdk .metrics .internal .exemplar .LongExemplarReservoir ;
1316import java .util .List ;
17+ import javax .annotation .Nullable ;
1418import javax .annotation .concurrent .ThreadSafe ;
1519
1620/**
2428 * at any time.
2529 */
2630@ ThreadSafe
27- public abstract class AggregatorHandle <T extends PointData , U extends ExemplarData > {
31+ public abstract class AggregatorHandle <T extends PointData > {
32+
33+ private static final String UNSUPPORTED_LONG_MESSAGE =
34+ "This aggregator does not support long values." ;
35+ private static final String UNSUPPORTED_DOUBLE_MESSAGE =
36+ "This aggregator does not support double values." ;
2837
2938 // A reservoir of sampled exemplars for this time period.
30- private final ExemplarReservoir <U > exemplarReservoir ;
39+ @ Nullable private final DoubleExemplarReservoir doubleReservoirFactory ;
40+ @ Nullable private final LongExemplarReservoir longReservoirFactory ;
41+ private final boolean isDoubleType ;
3142 private volatile boolean valuesRecorded = false ;
3243
33- protected AggregatorHandle (ExemplarReservoir <U > exemplarReservoir ) {
34- this .exemplarReservoir = exemplarReservoir ;
44+ protected AggregatorHandle (ExemplarReservoirFactory reservoirFactory ) {
45+ this .isDoubleType = isDoubleType ();
46+ if (isDoubleType ) {
47+ this .doubleReservoirFactory = reservoirFactory .createDoubleExemplarReservoir ();
48+ this .longReservoirFactory = null ;
49+ } else {
50+ this .doubleReservoirFactory = null ;
51+ this .longReservoirFactory = reservoirFactory .createLongExemplarReservoir ();
52+ }
3553 }
3654
3755 /**
@@ -44,35 +62,60 @@ public final T aggregateThenMaybeReset(
4462 valuesRecorded = false ;
4563 }
4664
47- return doAggregateThenMaybeReset (
65+ if (isDoubleType ) {
66+ return doAggregateThenMaybeResetDoubles (
67+ startEpochNanos ,
68+ epochNanos ,
69+ attributes ,
70+ throwUnsupportedIfNull (this .doubleReservoirFactory , UNSUPPORTED_DOUBLE_MESSAGE )
71+ .collectAndResetDoubles (attributes ),
72+ reset );
73+ }
74+ return doAggregateThenMaybeResetLongs (
4875 startEpochNanos ,
4976 epochNanos ,
5077 attributes ,
51- exemplarReservoir .collectAndReset (attributes ),
78+ throwUnsupportedIfNull (this .longReservoirFactory , UNSUPPORTED_LONG_MESSAGE )
79+ .collectAndResetLongs (attributes ),
5280 reset );
5381 }
5482
83+ /**
84+ * Indicates whether this {@link AggregatorHandle} supports double or long values.
85+ *
86+ * <p>If it supports doubles, it MUST implement {@link #doAggregateThenMaybeResetDoubles(long,
87+ * long, Attributes, List, boolean)} and {@link #doRecordDouble(double)}.
88+ *
89+ * <p>If it supports long, it MUST implement {@link #doAggregateThenMaybeResetLongs(long, long,
90+ * Attributes, List, boolean)} and {@link #doRecordLong(long)}.
91+ *
92+ * @return true if it supports doubles, false if it supports longs.
93+ */
94+ protected abstract boolean isDoubleType ();
95+
5596 /** Implementation of the {@link #aggregateThenMaybeReset(long, long, Attributes, boolean)} . */
56- protected abstract T doAggregateThenMaybeReset (
97+ protected T doAggregateThenMaybeResetDoubles (
5798 long startEpochNanos ,
5899 long epochNanos ,
59100 Attributes attributes ,
60- List <U > exemplars ,
61- boolean reset );
101+ List <DoubleExemplarData > exemplars ,
102+ boolean reset ) {
103+ throw new UnsupportedOperationException (UNSUPPORTED_DOUBLE_MESSAGE );
104+ }
62105
63- public final void recordLong (long value , Attributes attributes , Context context ) {
64- exemplarReservoir .offerLongMeasurement (value , attributes , context );
65- recordLong (value );
106+ /** Implementation of the {@link #aggregateThenMaybeReset(long, long, Attributes, boolean)} . */
107+ protected T doAggregateThenMaybeResetLongs (
108+ long startEpochNanos ,
109+ long epochNanos ,
110+ Attributes attributes ,
111+ List <LongExemplarData > exemplars ,
112+ boolean reset ) {
113+ throw new UnsupportedOperationException (UNSUPPORTED_LONG_MESSAGE );
66114 }
67115
68- /**
69- * Updates the current aggregator with a newly recorded {@code long} value.
70- *
71- * <p>Visible for Testing
72- *
73- * @param value the new {@code long} value to be added.
74- */
75- public final void recordLong (long value ) {
116+ public void recordLong (long value , Attributes attributes , Context context ) {
117+ throwUnsupportedIfNull (this .longReservoirFactory , UNSUPPORTED_LONG_MESSAGE )
118+ .offerLongMeasurement (value , attributes , context );
76119 doRecordLong (value );
77120 valuesRecorded = true ;
78121 }
@@ -82,23 +125,12 @@ public final void recordLong(long value) {
82125 * values.
83126 */
84127 protected void doRecordLong (long value ) {
85- throw new UnsupportedOperationException (
86- "This aggregator does not support recording long values." );
128+ throw new UnsupportedOperationException ("This aggregator does not support long values." );
87129 }
88130
89131 public final void recordDouble (double value , Attributes attributes , Context context ) {
90- exemplarReservoir .offerDoubleMeasurement (value , attributes , context );
91- recordDouble (value );
92- }
93-
94- /**
95- * Updates the current aggregator with a newly recorded {@code double} value.
96- *
97- * <p>Visible for Testing
98- *
99- * @param value the new {@code double} value to be added.
100- */
101- public final void recordDouble (double value ) {
132+ throwUnsupportedIfNull (this .doubleReservoirFactory , UNSUPPORTED_DOUBLE_MESSAGE )
133+ .offerDoubleMeasurement (value , attributes , context );
102134 doRecordDouble (value );
103135 valuesRecorded = true ;
104136 }
@@ -108,8 +140,7 @@ public final void recordDouble(double value) {
108140 * double values.
109141 */
110142 protected void doRecordDouble (double value ) {
111- throw new UnsupportedOperationException (
112- "This aggregator does not support recording double values." );
143+ throw new UnsupportedOperationException (UNSUPPORTED_DOUBLE_MESSAGE );
113144 }
114145
115146 /**
@@ -120,4 +151,11 @@ protected void doRecordDouble(double value) {
120151 public boolean hasRecordedValues () {
121152 return valuesRecorded ;
122153 }
154+
155+ private static <S > S throwUnsupportedIfNull (@ Nullable S value , String message ) {
156+ if (value == null ) {
157+ throw new UnsupportedOperationException (message );
158+ }
159+ return value ;
160+ }
123161}
0 commit comments