Skip to content

Commit 738d998

Browse files
authored
Stop extra copy of exponential histogram buckets (#5020)
1 parent c6d1ec1 commit 738d998

File tree

2 files changed

+25
-36
lines changed

2 files changed

+25
-36
lines changed

sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExponentialHistogramAggregator.java

+22-12
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,20 @@ public AggregatorHandle<ExponentialHistogramAccumulation, DoubleExemplarData> cr
5858
}
5959

6060
/**
61-
* This function is an immutable merge. It firstly combines the sum and zero count. Then it
62-
* performs a merge using the buckets from both accumulations, without modifying those
63-
* accumulations.
64-
*
65-
* @param previous the previously captured accumulation
66-
* @param current the newly captured (delta) accumulation
67-
* @return the result of the merge of the given accumulations.
61+
* Merge the exponential histogram accumulations. Mutates the {@link
62+
* ExponentialHistogramAccumulation#getPositiveBuckets()} and {@link
63+
* ExponentialHistogramAccumulation#getNegativeBuckets()} of {@code previous}. Mutating buckets is
64+
* acceptable because copies are already made in {@link Handle#doAccumulateThenReset(List)}.
6865
*/
6966
@Override
7067
public ExponentialHistogramAccumulation merge(
7168
ExponentialHistogramAccumulation previous, ExponentialHistogramAccumulation current) {
7269

7370
// Create merged buckets
7471
DoubleExponentialHistogramBuckets posBuckets =
75-
DoubleExponentialHistogramBuckets.merge(
76-
previous.getPositiveBuckets(), current.getPositiveBuckets());
72+
merge(previous.getPositiveBuckets(), current.getPositiveBuckets());
7773
DoubleExponentialHistogramBuckets negBuckets =
78-
DoubleExponentialHistogramBuckets.merge(
79-
previous.getNegativeBuckets(), current.getNegativeBuckets());
74+
merge(previous.getNegativeBuckets(), current.getNegativeBuckets());
8075

8176
// resolve possible scale difference due to merge
8277
int commonScale = Math.min(posBuckets.getScale(), negBuckets.getScale());
@@ -95,7 +90,7 @@ public ExponentialHistogramAccumulation merge(
9590
max = current.getMax();
9691
}
9792
return ExponentialHistogramAccumulation.create(
98-
posBuckets.getScale(),
93+
commonScale,
9994
previous.getSum() + current.getSum(),
10095
previous.hasMinMax() || current.hasMinMax(),
10196
min,
@@ -106,6 +101,21 @@ public ExponentialHistogramAccumulation merge(
106101
current.getExemplars());
107102
}
108103

104+
/**
105+
* Merge the exponential histogram buckets. If {@code a} is empty, return {@code b}. If {@code b}
106+
* is empty, return {@code a}. Else merge {@code b} into {@code a}.
107+
*/
108+
private static DoubleExponentialHistogramBuckets merge(
109+
DoubleExponentialHistogramBuckets a, DoubleExponentialHistogramBuckets b) {
110+
if (b.getTotalCount() == 0) {
111+
return a;
112+
} else if (a.getTotalCount() == 0) {
113+
return b;
114+
}
115+
a.mergeInto(b);
116+
return a;
117+
}
118+
109119
@Override
110120
public MetricData toMetricData(
111121
Resource resource,

sdk/metrics/src/main/java/io/opentelemetry/sdk/metrics/internal/aggregator/DoubleExponentialHistogramBuckets.java

+3-24
Original file line numberDiff line numberDiff line change
@@ -132,30 +132,9 @@ void downscale(int by) {
132132
this.exponentialHistogramIndexer = ExponentialHistogramIndexer.get(this.scale);
133133
}
134134

135-
/**
136-
* Immutable method for merging. This method copies the first set of buckets, performs the merge
137-
* on the copy, and returns the copy.
138-
*
139-
* @param a first buckets
140-
* @param b second buckets
141-
* @return A new set of buckets, the result
142-
*/
143-
static DoubleExponentialHistogramBuckets merge(
144-
DoubleExponentialHistogramBuckets a, DoubleExponentialHistogramBuckets b) {
145-
if (b.counts.isEmpty()) {
146-
return a;
147-
} else if (a.counts.isEmpty()) {
148-
return b;
149-
}
150-
DoubleExponentialHistogramBuckets copy = a.copy();
151-
copy.mergeWith(b/* additive= */ );
152-
return copy;
153-
}
154-
155135
/**
156136
* This method merges this instance with another set of buckets. It alters the underlying bucket
157-
* counts and scale of this instance only, so it is to be used with caution. For immutability, use
158-
* the static merge() method.
137+
* counts and scale of this instance only, so it is to be used with caution.
159138
*
160139
* <p>The bucket counts of this instance will be added to or subtracted from depending on the
161140
* additive parameter.
@@ -164,7 +143,7 @@ static DoubleExponentialHistogramBuckets merge(
164143
*
165144
* @param other the histogram that will be merged into this one
166145
*/
167-
private void mergeWith(DoubleExponentialHistogramBuckets other) {
146+
void mergeInto(DoubleExponentialHistogramBuckets other) {
168147
if (other.counts.isEmpty()) {
169148
return;
170149
}
@@ -195,7 +174,7 @@ private void mergeWith(DoubleExponentialHistogramBuckets other) {
195174
// since we changed scale of this, we need to know the new difference between the two scales
196175
deltaOther = other.scale - this.scale;
197176

198-
// do actual merging of other into this. Will decrement or increment depending on sign.
177+
// do actual merging of other into this.
199178
for (int i = other.getOffset(); i <= other.counts.getIndexEnd(); i++) {
200179
if (!this.counts.increment(i >> deltaOther, other.counts.get(i))) {
201180
// This should never occur if scales and windows are calculated without bugs

0 commit comments

Comments
 (0)