private int doNext(int doc) throws IOException { 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].scorer.advance(doc); 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; } // advance head for next iteration doc = lead.doc = lead.scorer.advance(doc); } }
@Override public int nextDoc() throws IOException { lead.doc = lead.scorer.nextDoc(); return lastDoc = doNext(lead.doc); }
@Override public int advance(int target) throws IOException { lead.doc = lead.scorer.advance(target); return lastDoc = doNext(lead.doc); }