Forráskód Böngészése

Prevent Massive Oversizing of Buckets List in BucketsAggregator (#74962)

We must pre-size the buckets list by the number of buckets in the ord,
not all the ords combined. This led to a reported OOM.
Also, removed a redundant loop here.
Armin Braun 4 éve
szülő
commit
a01ba7ff9b

+ 5 - 6
server/src/main/java/org/elasticsearch/search/aggregations/bucket/BucketsAggregator.java

@@ -163,10 +163,6 @@ public abstract class BucketsAggregator extends AggregatorBase {
         }
         InternalAggregations[] result = new InternalAggregations[bucketOrdsToCollect.length];
         for (int ord = 0; ord < bucketOrdsToCollect.length; ord++) {
-            InternalAggregation[] slice = new InternalAggregation[subAggregators.length];
-            for (int i = 0; i < subAggregators.length; i++) {
-                slice[i] = aggregations[i][ord];
-            }
             final int thisOrd = ord;
             result[ord] = InternalAggregations.from(new AbstractList<InternalAggregation>() {
                 @Override
@@ -301,8 +297,11 @@ public abstract class BucketsAggregator extends AggregatorBase {
     protected final <B> InternalAggregation[] buildAggregationsForVariableBuckets(long[] owningBucketOrds, LongKeyedBucketOrds bucketOrds,
             BucketBuilderForVariable<B> bucketBuilder, ResultBuilderForVariable<B> resultBuilder) throws IOException {
         long totalOrdsToCollect = 0;
+        final int[] bucketsInOrd = new int[owningBucketOrds.length];
         for (int ordIdx = 0; ordIdx < owningBucketOrds.length; ordIdx++) {
-            totalOrdsToCollect += bucketOrds.bucketsInOrd(owningBucketOrds[ordIdx]);
+            final long bucketCount = bucketOrds.bucketsInOrd(owningBucketOrds[ordIdx]);
+            bucketsInOrd[ordIdx] = (int) bucketCount;
+            totalOrdsToCollect += bucketCount;
         }
         if (totalOrdsToCollect > Integer.MAX_VALUE) {
             throw new AggregationExecutionException("Can't collect more than [" + Integer.MAX_VALUE
@@ -321,7 +320,7 @@ public abstract class BucketsAggregator extends AggregatorBase {
         InternalAggregation[] results = new InternalAggregation[owningBucketOrds.length];
         b = 0;
         for (int ordIdx = 0; ordIdx < owningBucketOrds.length; ordIdx++) {
-            List<B> buckets = new ArrayList<>((int) bucketOrds.size());
+            List<B> buckets = new ArrayList<>(bucketsInOrd[ordIdx]);
             LongKeyedBucketOrds.BucketOrdsEnum ordsEnum = bucketOrds.ordsEnum(owningBucketOrds[ordIdx]);
             while(ordsEnum.next()) {
                 if (bucketOrdsToCollect[b] != ordsEnum.ord()) {