-
Notifications
You must be signed in to change notification settings - Fork 25.3k
Speed up date_histogram without children #63643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3eb94bc
3f99f04
6c8cb0b
995ca24
d7becd8
0a1987d
1258ad4
da02047
9157f00
20047dc
e69628e
607ae5f
0e68cad
9754fb0
0750aa8
c57c98a
4021327
7a44c21
73aaa45
b73df70
b7e8dcc
7c18141
2d04e35
102e526
e333cbb
e2fd164
46a1015
deb5684
de96179
4e9c918
f13a8ae
6b33247
14b4962
2fd7e53
97c35cd
6c7eaa1
5b5ac7b
117eb77
08fee6c
ce640e3
523d420
f1ae980
9da87c5
3d3ea19
4291b70
ff41cdb
a5f0009
ec5bf41
6b5c09a
9c26fd8
c5b0464
66684f2
b1c79b2
997e9b9
9494447
bfb10bd
1e1b1dd
ca09463
5b5d6cc
fc1444d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
* Licensed to Elasticsearch under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
package org.elasticsearch.search.aggregations; | ||
|
||
import org.apache.lucene.index.LeafReaderContext; | ||
import org.apache.lucene.search.ScoreMode; | ||
import org.elasticsearch.common.CheckedFunction; | ||
import org.elasticsearch.search.profile.aggregation.InternalAggregationProfileTree; | ||
|
||
import java.io.IOException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.BiConsumer; | ||
|
||
/** | ||
* An {@linkplain Aggregator} that delegates collection to another | ||
* {@linkplain Aggregator} and then translates its results into the results | ||
* you'd expect from another aggregation. | ||
*/ | ||
public abstract class AdaptingAggregator extends Aggregator { | ||
private final Aggregator parent; | ||
private final Aggregator delegate; | ||
|
||
public AdaptingAggregator( | ||
Aggregator parent, | ||
AggregatorFactories subAggregators, | ||
CheckedFunction<AggregatorFactories, Aggregator, IOException> delegate | ||
) throws IOException { | ||
// Its important we set parent first or else when we build the sub-aggregators they can fail because they'll call this.parent. | ||
this.parent = parent; | ||
/* | ||
* Lock the parent of the sub-aggregators to *this* instead of to | ||
* the delegate. This keeps the parent link shaped like the requested | ||
* agg tree. Thisis how it has always been and some aggs rely on it. | ||
*/ | ||
this.delegate = delegate.apply(subAggregators.fixParent(this)); | ||
assert this.delegate.parent() == parent : "invalid parent set on delegate"; | ||
} | ||
|
||
/** | ||
* Adapt the result from the collecting {@linkplain Aggregator} into the | ||
* result expected by this {@linkplain Aggregator}. | ||
*/ | ||
protected abstract InternalAggregation adapt(InternalAggregation delegateResult); | ||
|
||
@Override | ||
public final void close() { | ||
delegate.close(); | ||
} | ||
|
||
@Override | ||
public final ScoreMode scoreMode() { | ||
return delegate.scoreMode(); | ||
} | ||
|
||
@Override | ||
public final String name() { | ||
return delegate.name(); | ||
} | ||
|
||
@Override | ||
public final Aggregator parent() { | ||
return parent; | ||
} | ||
|
||
@Override | ||
public final Aggregator subAggregator(String name) { | ||
return delegate.subAggregator(name); | ||
} | ||
|
||
@Override | ||
public final LeafBucketCollector getLeafCollector(LeafReaderContext ctx) throws IOException { | ||
return delegate.getLeafCollector(ctx); | ||
} | ||
|
||
@Override | ||
public final void preCollection() throws IOException { | ||
delegate.preCollection(); | ||
} | ||
|
||
@Override | ||
public final InternalAggregation[] buildAggregations(long[] owningBucketOrds) throws IOException { | ||
InternalAggregation[] delegateResults = delegate.buildAggregations(owningBucketOrds); | ||
InternalAggregation[] result = new InternalAggregation[owningBucketOrds.length]; | ||
for (int ordIdx = 0; ordIdx < owningBucketOrds.length; ordIdx++) { | ||
result[ordIdx] = adapt(delegateResults[ordIdx]); | ||
} | ||
return result; | ||
} | ||
|
||
@Override | ||
public final InternalAggregation buildEmptyAggregation() { | ||
return adapt(delegate.buildEmptyAggregation()); | ||
} | ||
|
||
@Override | ||
public final Aggregator[] subAggregators() { | ||
return delegate.subAggregators(); | ||
} | ||
|
||
@Override | ||
public void collectDebugInfo(BiConsumer<String, Object> add) { | ||
super.collectDebugInfo(add); | ||
add.accept("delegate", InternalAggregationProfileTree.typeFromAggregator(delegate)); | ||
Map<String, Object> delegateDebug = new HashMap<>(); | ||
delegate.collectDebugInfo(delegateDebug::put); | ||
add.accept("delegate_debug", delegateDebug); | ||
} | ||
|
||
public Aggregator delegate() { | ||
return delegate; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -227,6 +227,27 @@ public int countAggregators() { | |
return factories.length; | ||
} | ||
|
||
/** | ||
* This returns a copy of {@link AggregatorFactories} modified so that | ||
* calls to {@link #createSubAggregators} will ignore the provided parent | ||
* aggregator and always use {@code fixedParent} provided in to this | ||
* method. | ||
* <p> | ||
* {@link AdaptingAggregator} uses this to make sure that sub-aggregators | ||
* get the {@link AdaptingAggregator} aggregator itself as the parent. | ||
*/ | ||
public AggregatorFactories fixParent(Aggregator fixedParent) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could use some javadoc. It's not clear from the context that it's intended to be used with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
AggregatorFactories previous = this; | ||
return new AggregatorFactories(factories) { | ||
@Override | ||
public Aggregator[] createSubAggregators(SearchContext searchContext, Aggregator parent, CardinalityUpperBound cardinality) | ||
throws IOException { | ||
// Note that we're throwing out the "parent" passed in to this method and using the parent passed to fixParent | ||
return previous.createSubAggregators(searchContext, fixedParent, cardinality); | ||
} | ||
}; | ||
} | ||
|
||
/** | ||
* A mutable collection of {@link AggregationBuilder}s and | ||
* {@link PipelineAggregationBuilder}s. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my first read, I thought we might round down to
null
. How about:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍