LUCENE-4791: optimize ConjunctionTermScorer to use skipping on first term

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1449141 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2013-02-22 17:21:22 +00:00
parent 302c3ed37e
commit c6c03fe031
2 changed files with 24 additions and 12 deletions
lucene
CHANGES.txt
core/src/java/org/apache/lucene/search

View File

@ -245,6 +245,12 @@ Bug Fixes
cached datastructure. Otherwise this can cause inconsistencies with readers
at different points in time. (Robert Muir)
* LUCENE-4791: A conjunction of terms (ConjunctionTermScorer) scanned on
the lowest frequency term instead of skipping, leading to potentially
large performance impacts for many non-random or non-uniform
term distributions. (John Wang, yonik)
Documentation
* LUCENE-4718: Fixed documentation of oal.queryparser.classic.

View File

@ -50,26 +50,32 @@ class ConjunctionTermScorer extends Scorer {
}
private int doNext(int doc) throws IOException {
do {
if (lead.doc == DocIdSetIterator.NO_MORE_DOCS) {
return NO_MORE_DOCS;
}
advanceHead: do {
for(;;) {
// doc may already be NO_MORE_DOCS here, but we don't check explicitly
// since all scorers should advance to NO_MORE_DOCS, match, then
// return that value.
advanceHead: for(;;) {
for (int i = 1; i < docsAndFreqs.length; i++) {
// invariant: docsAndFreqs[i].doc <= doc at this point.
// docsAndFreqs[i].doc may already be equal to doc if we "broke advanceHead"
// on the previous iteration and the advance on the lead scorer exactly matched.
if (docsAndFreqs[i].doc < doc) {
docsAndFreqs[i].doc = docsAndFreqs[i].docs.advance(doc);
}
if (docsAndFreqs[i].doc > doc) {
// DocsEnum beyond the current doc - break and advance lead
break advanceHead;
if (docsAndFreqs[i].doc > doc) {
// DocsEnum beyond the current doc - break and advance lead to the new highest doc.
doc = docsAndFreqs[i].doc;
break advanceHead;
}
}
}
// success - all DocsEnums are on the same doc
return doc;
} while (true);
}
// advance head for next iteration
doc = lead.doc = lead.docs.nextDoc();
} while (true);
doc = lead.doc = lead.docs.advance(doc);
}
}
@Override