@@ -46,8 +46,8 @@ class WeightedAvgAggregator extends NumericMetricsAggregator.SingleValue {
46
46
private final MultiValuesSource .NumericMultiValuesSource valuesSources ;
47
47
48
48
private DoubleArray weights ;
49
- private DoubleArray sums ;
50
- private DoubleArray sumCompensations ;
49
+ private DoubleArray valueSums ;
50
+ private DoubleArray valueCompensations ;
51
51
private DoubleArray weightCompensations ;
52
52
private DocValueFormat format ;
53
53
@@ -60,8 +60,8 @@ class WeightedAvgAggregator extends NumericMetricsAggregator.SingleValue {
60
60
if (valuesSources != null ) {
61
61
final BigArrays bigArrays = context .bigArrays ();
62
62
weights = bigArrays .newDoubleArray (1 , true );
63
- sums = bigArrays .newDoubleArray (1 , true );
64
- sumCompensations = bigArrays .newDoubleArray (1 , true );
63
+ valueSums = bigArrays .newDoubleArray (1 , true );
64
+ valueCompensations = bigArrays .newDoubleArray (1 , true );
65
65
weightCompensations = bigArrays .newDoubleArray (1 , true );
66
66
}
67
67
}
@@ -80,13 +80,15 @@ public LeafBucketCollector getLeafCollector(LeafReaderContext ctx,
80
80
final BigArrays bigArrays = context .bigArrays ();
81
81
final SortedNumericDoubleValues docValues = valuesSources .getField (VALUE_FIELD .getPreferredName (), ctx );
82
82
final SortedNumericDoubleValues docWeights = valuesSources .getField (WEIGHT_FIELD .getPreferredName (), ctx );
83
+ final CompensatedSum compensatedValueSum = new CompensatedSum (0 , 0 );
84
+ final CompensatedSum compensatedWeightSum = new CompensatedSum (0 , 0 );
83
85
84
86
return new LeafBucketCollectorBase (sub , docValues ) {
85
87
@ Override
86
88
public void collect (int doc , long bucket ) throws IOException {
87
89
weights = bigArrays .grow (weights , bucket + 1 );
88
- sums = bigArrays .grow (sums , bucket + 1 );
89
- sumCompensations = bigArrays .grow (sumCompensations , bucket + 1 );
90
+ valueSums = bigArrays .grow (valueSums , bucket + 1 );
91
+ valueCompensations = bigArrays .grow (valueCompensations , bucket + 1 );
90
92
weightCompensations = bigArrays .grow (weightCompensations , bucket + 1 );
91
93
92
94
if (docValues .advanceExact (doc ) && docWeights .advanceExact (doc )) {
@@ -102,42 +104,43 @@ public void collect(int doc, long bucket) throws IOException {
102
104
final int numValues = docValues .docValueCount ();
103
105
assert numValues > 0 ;
104
106
107
+ double valueSum = valueSums .get (bucket );
108
+ double valueCompensation = valueCompensations .get (bucket );
109
+ compensatedValueSum .reset (valueSum , valueCompensation );
110
+
111
+ double weightSum = weights .get (bucket );
112
+ double weightCompensation = weightCompensations .get (bucket );
113
+ compensatedWeightSum .reset (weightSum , weightCompensation );
114
+
105
115
for (int i = 0 ; i < numValues ; i ++) {
106
- kahanSum (docValues .nextValue () * weight , sums , sumCompensations , bucket );
107
- kahanSum (weight , weights , weightCompensations , bucket );
116
+ compensatedValueSum . add (docValues .nextValue () * weight );
117
+ compensatedWeightSum . add (weight );
108
118
}
119
+
120
+ valueSums .set (bucket , compensatedValueSum .value ());
121
+ valueCompensations .set (bucket , compensatedValueSum .delta ());
122
+ weights .set (bucket , compensatedWeightSum .value ());
123
+ weightCompensations .set (bucket , compensatedWeightSum .delta ());
109
124
}
110
125
}
111
126
};
112
127
}
113
128
114
- private static void kahanSum (double value , DoubleArray values , DoubleArray compensations , long bucket ) {
115
- // Compute the sum of double values with Kahan summation algorithm which is more
116
- // accurate than naive summation.
117
- double sum = values .get (bucket );
118
- double compensation = compensations .get (bucket );
119
-
120
- CompensatedSum kahanSummation = new CompensatedSum (sum , compensation )
121
- .add (value );
122
-
123
- values .set (bucket , kahanSummation .value ());
124
- compensations .set (bucket , kahanSummation .delta ());
125
- }
126
129
127
130
@ Override
128
131
public double metric (long owningBucketOrd ) {
129
- if (valuesSources == null || owningBucketOrd >= sums .size ()) {
132
+ if (valuesSources == null || owningBucketOrd >= valueSums .size ()) {
130
133
return Double .NaN ;
131
134
}
132
- return sums .get (owningBucketOrd ) / weights .get (owningBucketOrd );
135
+ return valueSums .get (owningBucketOrd ) / weights .get (owningBucketOrd );
133
136
}
134
137
135
138
@ Override
136
139
public InternalAggregation buildAggregation (long bucket ) {
137
- if (valuesSources == null || bucket >= sums .size ()) {
140
+ if (valuesSources == null || bucket >= valueSums .size ()) {
138
141
return buildEmptyAggregation ();
139
142
}
140
- return new InternalWeightedAvg (name , sums .get (bucket ), weights .get (bucket ), format , pipelineAggregators (), metaData ());
143
+ return new InternalWeightedAvg (name , valueSums .get (bucket ), weights .get (bucket ), format , pipelineAggregators (), metaData ());
141
144
}
142
145
143
146
@ Override
@@ -147,7 +150,7 @@ public InternalAggregation buildEmptyAggregation() {
147
150
148
151
@ Override
149
152
public void doClose () {
150
- Releasables .close (weights , sums , sumCompensations , weightCompensations );
153
+ Releasables .close (weights , valueSums , valueCompensations , weightCompensations );
151
154
}
152
155
153
156
}
0 commit comments