Index: lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java =================================================================== --- lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java (revision 1180859) +++ lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java (working copy) @@ -17,6 +17,9 @@ * limitations under the License. */ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -33,6 +36,7 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.NamedThreadFactory; +import org.apache.lucene.util._TestUtil; public class TestBooleanQuery extends LuceneTestCase { @@ -183,6 +187,113 @@ dir1.close(); dir2.close(); } + + public void testBS2DisjunctionNextVsAdvance() throws Exception { + final Directory d = newDirectory(); + final RandomIndexWriter w = new RandomIndexWriter(random, d); + final int numDocs = atLeast(300); + for(int docUpto=0;docUpto numTerms) { + terms.remove(random.nextInt(terms.size())); + } + + if (VERBOSE) { + System.out.println(" terms=" + terms); + } + + final BooleanQuery q = new BooleanQuery(); + for(String term : terms) { + q.add(new BooleanClause(new TermQuery(new Term("field", term)), BooleanClause.Occur.SHOULD)); + } + + Weight weight = s.createNormalizedWeight(q); + + Scorer scorer = weight.scorer(r.getTopReaderContext().leaves()[0], + true, false, null); + + // First pass: just use .nextDoc() to gather all hits + final List hits = new ArrayList(); + while(scorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { + hits.add(new ScoreDoc(scorer.docID(), scorer.score())); + } + + if (VERBOSE) { + System.out.println(" " + hits.size() + " hits"); + } + + // Now, randomly next/advance through the list and + // verify exact match: + for(int iter2=0;iter2<10;iter2++) { + + weight = s.createNormalizedWeight(q); + scorer = weight.scorer(r.getTopReaderContext().leaves()[0], + true, false, null); + + if (VERBOSE) { + System.out.println(" iter2=" + iter2); + } + + int upto = -1; + while(upto < hits.size()) { + final int nextUpto; + final int nextDoc; + final int left = hits.size() - upto; + if (left == 1 || random.nextBoolean()) { + // next + nextUpto = 1+upto; + nextDoc = scorer.nextDoc(); + } else { + // advance + int inc = _TestUtil.nextInt(random, 1, left-1); + nextUpto = inc + upto; + nextDoc = scorer.advance(hits.get(nextUpto).doc); + } + + if (nextUpto == hits.size()) { + assertEquals(DocIdSetIterator.NO_MORE_DOCS, nextDoc); + } else { + final ScoreDoc hit = hits.get(nextUpto); + assertEquals(hit.doc, nextDoc); + // Test for precise float equality: + assertTrue("doc " + hit.doc + " has wrong score: expected=" + hit.score + " actual=" + scorer.score(), hit.score == scorer.score()); + } + upto = nextUpto; + } + } + } + + r.close(); + d.close(); + } } - -