Reduce branches in TopChildrenQuery
The branches used in the score method can be moved into the scorer call and be essentially a constant operation rather than a linear operation depending on the number of parent docs.
This commit is contained in:
parent
52654179e7
commit
a3a2ca0ad3
|
@ -320,7 +320,33 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite {
|
||||||
public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException {
|
public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException {
|
||||||
ParentDoc[] readerParentDocs = parentDocs.get(context.reader().getCoreCacheKey());
|
ParentDoc[] readerParentDocs = parentDocs.get(context.reader().getCoreCacheKey());
|
||||||
if (readerParentDocs != null) {
|
if (readerParentDocs != null) {
|
||||||
return new ParentScorer(this, readerParentDocs);
|
if (scoreType == ScoreType.MAX) {
|
||||||
|
return new ParentScorer(this, readerParentDocs) {
|
||||||
|
@Override
|
||||||
|
public float score() throws IOException {
|
||||||
|
assert doc.docId >= 0 || doc.docId < NO_MORE_DOCS;
|
||||||
|
return doc.maxScore;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (scoreType == ScoreType.AVG) {
|
||||||
|
return new ParentScorer(this, readerParentDocs) {
|
||||||
|
@Override
|
||||||
|
public float score() throws IOException {
|
||||||
|
assert doc.docId >= 0 || doc.docId < NO_MORE_DOCS;
|
||||||
|
return doc.sumScores / doc.count;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (scoreType == ScoreType.SUM) {
|
||||||
|
return new ParentScorer(this, readerParentDocs) {
|
||||||
|
@Override
|
||||||
|
public float score() throws IOException {
|
||||||
|
assert doc.docId >= 0 || doc.docId < NO_MORE_DOCS;
|
||||||
|
return doc.sumScores;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new ElasticSearchIllegalStateException("No support for score type [" + scoreType + "]");
|
||||||
}
|
}
|
||||||
return new EmptyScorer(this);
|
return new EmptyScorer(this);
|
||||||
}
|
}
|
||||||
|
@ -331,31 +357,26 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParentScorer extends Scorer {
|
static abstract class ParentScorer extends Scorer {
|
||||||
|
private final ParentDoc spare = new ParentDoc();
|
||||||
private final ParentDoc[] docs;
|
protected final ParentDoc[] docs;
|
||||||
|
protected ParentDoc doc = spare;
|
||||||
private int index = -1;
|
private int index = -1;
|
||||||
|
|
||||||
private ParentScorer(ParentWeight weight, ParentDoc[] docs) throws IOException {
|
ParentScorer(ParentWeight weight, ParentDoc[] docs) throws IOException {
|
||||||
super(weight);
|
super(weight);
|
||||||
this.docs = docs;
|
this.docs = docs;
|
||||||
|
spare.docId = -1;
|
||||||
|
spare.count = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int docID() {
|
public final int docID() {
|
||||||
if (index == -1) {
|
return doc.docId;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index >= docs.length) {
|
|
||||||
return NO_MORE_DOCS;
|
|
||||||
}
|
|
||||||
return docs[index].docId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int advance(int target) throws IOException {
|
public final int advance(int target) throws IOException {
|
||||||
int doc;
|
int doc;
|
||||||
while ((doc = nextDoc()) < target) {
|
while ((doc = nextDoc()) < target) {
|
||||||
}
|
}
|
||||||
|
@ -363,32 +384,22 @@ public class TopChildrenQuery extends Query implements SearchContext.Rewrite {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int nextDoc() throws IOException {
|
public final int nextDoc() throws IOException {
|
||||||
if (++index >= docs.length) {
|
if (++index >= docs.length) {
|
||||||
return NO_MORE_DOCS;
|
doc = spare;
|
||||||
|
doc.count = 0;
|
||||||
|
return (doc.docId = NO_MORE_DOCS);
|
||||||
}
|
}
|
||||||
return docs[index].docId;
|
return (doc = docs[index]).docId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float score() throws IOException {
|
public final int freq() throws IOException {
|
||||||
if (scoreType == ScoreType.MAX) {
|
return doc.count; // The number of matches in the child doc, which is propagated to parent
|
||||||
return docs[index].maxScore;
|
|
||||||
} else if (scoreType == ScoreType.AVG) {
|
|
||||||
return docs[index].sumScores / docs[index].count;
|
|
||||||
} else if (scoreType == ScoreType.SUM) {
|
|
||||||
return docs[index].sumScores;
|
|
||||||
}
|
|
||||||
throw new ElasticSearchIllegalStateException("No support for score type [" + scoreType + "]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int freq() throws IOException {
|
public final long cost() {
|
||||||
return docs[index].count; // The number of matches in the child doc, which is propagated to parent
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long cost() {
|
|
||||||
return docs.length;
|
return docs.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue