Skip to content

Commit

Permalink
Profiler: Don’t profile NEXTDOC for ConstantScoreQuery. (#33196)
Browse files Browse the repository at this point in the history
* Profiler: Don’t profile NEXTDOC for ConstantScoreQuery.

A ConstantScore query will return the iterator of its inner query.
However, when profiling, the constant score query is wrapped separately
from its inner query, which distorts the times emitted by the profiler.
Return the iterator directly in such a case.

Closes #23430
  • Loading branch information
iverase authored Sep 19, 2018
1 parent 013b64a commit 7f473b6
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ public Timer getTimer(T timing) {
return timings[timing.ordinal()];
}

public void setTimer(T timing, Timer timer) {
timings[timing.ordinal()] = timer;
}

/** Convert this record to a map from timingType to times. */
public Map<String, Long> toTimingMap() {
Map<String, Long> map = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

package org.elasticsearch.search.profile.query;

import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
import org.apache.lucene.search.Weight;
Expand All @@ -36,7 +38,10 @@ final class ProfileScorer extends Scorer {

private final Scorer scorer;
private ProfileWeight profileWeight;

private final Timer scoreTimer, nextDocTimer, advanceTimer, matchTimer, shallowAdvanceTimer, computeMaxScoreTimer;
private final boolean isConstantScoreQuery;


ProfileScorer(ProfileWeight w, Scorer scorer, QueryProfileBreakdown profile) throws IOException {
super(w);
Expand All @@ -48,6 +53,26 @@ final class ProfileScorer extends Scorer {
matchTimer = profile.getTimer(QueryTimingType.MATCH);
shallowAdvanceTimer = profile.getTimer(QueryTimingType.SHALLOW_ADVANCE);
computeMaxScoreTimer = profile.getTimer(QueryTimingType.COMPUTE_MAX_SCORE);
ProfileScorer profileScorer = null;
if (w.getQuery() instanceof ConstantScoreQuery && scorer instanceof ProfileScorer) {
//Case when we have a totalHits query and it is not cached
profileScorer = (ProfileScorer) scorer;
} else if (w.getQuery() instanceof ConstantScoreQuery && scorer.getChildren().size() == 1) {
//Case when we have a top N query. If the scorer has no children, it is because it is cached
//and in that case we do not do any special treatment
Scorable childScorer = scorer.getChildren().iterator().next().child;
if (childScorer instanceof ProfileScorer) {
profileScorer = (ProfileScorer) childScorer;
}
}
if (profileScorer != null) {
isConstantScoreQuery = true;
profile.setTimer(QueryTimingType.NEXT_DOC, profileScorer.nextDocTimer);
profile.setTimer(QueryTimingType.ADVANCE, profileScorer.advanceTimer);
profile.setTimer(QueryTimingType.MATCH, profileScorer.matchTimer);
} else {
isConstantScoreQuery = false;
}
}

@Override
Expand Down Expand Up @@ -77,6 +102,9 @@ public Collection<ChildScorable> getChildren() throws IOException {

@Override
public DocIdSetIterator iterator() {
if (isConstantScoreQuery) {
return scorer.iterator();
}
final DocIdSetIterator in = scorer.iterator();
return new DocIdSetIterator() {

Expand Down Expand Up @@ -114,6 +142,9 @@ public long cost() {

@Override
public TwoPhaseIterator twoPhaseIterator() {
if (isConstantScoreQuery) {
return scorer.twoPhaseIterator();
}
final TwoPhaseIterator in = scorer.twoPhaseIterator();
if (in == null) {
return null;
Expand Down
Loading

0 comments on commit 7f473b6

Please sign in to comment.