Index: src/test/org/apache/lucene/index/TestIndexReader.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexReader.java (revision 739247) +++ src/test/org/apache/lucene/index/TestIndexReader.java (working copy) @@ -40,8 +40,10 @@ import org.apache.lucene.document.SetBasedFieldSelector; import org.apache.lucene.index.IndexReader.FieldOption; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MultiReaderHitCollector; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.Query; import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; @@ -1589,4 +1591,55 @@ dir.close(); } + + // LUCENE-1483 + public void testDocsInOrderSearch() throws Throwable { + Directory dir = new MockRAMDirectory(); + + IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(), + IndexWriter.MaxFieldLength.LIMITED); + writer.addDocument(createDocument("a")); + writer.commit(); + writer.addDocument(createDocument("a")); + writer.addDocument(createDocument("a")); + writer.close(); + + Query q = new TermQuery(new Term("id", "a")); + + IndexSearcher s = new IndexSearcher(dir); + s.search(q, new MultiReaderHitCollector() { + int lastDocBase = -1; + public void setNextReader(IndexReader reader, int docBase) { + if (lastDocBase == -1) { + assertEquals(1, docBase); + } else if (lastDocBase == 1) { + assertEquals(0, docBase); + } else { + fail(); + } + lastDocBase = docBase; + } + public void collect(int doc, float score) {} + }); + s.close(); + + IndexReader r = IndexReader.open(dir); + s = new IndexSearcher(r, true); + s.search(q, new MultiReaderHitCollector() { + int lastDocBase = -1; + public void setNextReader(IndexReader reader, int docBase) { + if (lastDocBase == -1) { + assertEquals(0, docBase); + } else if (lastDocBase == 0) { + assertEquals(1, docBase); + } else { + fail(); + } + lastDocBase = docBase; + } + public void collect(int doc, float score) {} + }); + s.close(); + r.close(); + } } Index: src/java/org/apache/lucene/search/IndexSearcher.java =================================================================== --- src/java/org/apache/lucene/search/IndexSearcher.java (revision 739247) +++ src/java/org/apache/lucene/search/IndexSearcher.java (working copy) @@ -48,7 +48,7 @@ * @throws IOException if there is a low-level IO error */ public IndexSearcher(String path) throws CorruptIndexException, IOException { - this(IndexReader.open(path), true); + this(IndexReader.open(path), true, false); } /** Creates a searcher searching the index in the provided directory. @@ -56,18 +56,28 @@ * @throws IOException if there is a low-level IO error */ public IndexSearcher(Directory directory) throws CorruptIndexException, IOException { - this(IndexReader.open(directory), true); + this(IndexReader.open(directory), true, false); } /** Creates a searcher searching the provided index. */ public IndexSearcher(IndexReader r) { - this(r, false); + this(r, false, false); } - private IndexSearcher(IndexReader r, boolean closeReader) { + /** Expert: Creates a searcher searching the provided + * index, specifying whether searches must visit the + * documents in order. By default, segments are + * searched in order of decreasing maxDoc(); if you pass + * true for docsInOrder, they will instead be searched + * in their natural (unsorted) order.*/ + public IndexSearcher(IndexReader r, boolean docsInOrder) { + this(r, false, docsInOrder); + } + + private IndexSearcher(IndexReader r, boolean closeReader, boolean docsInOrder) { reader = r; this.closeReader = closeReader; - sortSubReaders(); + sortSubReaders(docsInOrder); } protected void gatherSubReaders(List allSubReaders, IndexReader r) { @@ -84,7 +94,7 @@ static private final IndexReader[] indexReaderZeroArray = new IndexReader[0]; - protected void sortSubReaders() { + protected void sortSubReaders(boolean docsInOrder) { List subReadersList = new ArrayList(); gatherSubReaders(subReadersList, reader); @@ -97,28 +107,31 @@ maxDoc += sortedSubReaders[i].maxDoc(); // compute maxDocs } - // sort readers and starts - SorterTemplate sorter = new SorterTemplate() { - protected int compare(int i, int j) { - int num1 = sortedSubReaders[i].numDocs(); - int num2 = sortedSubReaders[j].numDocs(); - if (num1 > num2) - return -1; - if (num1 < num2) - return 1; - return 0; - } - protected void swap(int i, int j) { - IndexReader temp = sortedSubReaders[i]; - sortedSubReaders[i] = sortedSubReaders[j]; - sortedSubReaders[j] = temp; + if (!docsInOrder) { - int tempInt = sortedStarts[i]; - sortedStarts[i] = sortedStarts[j]; - sortedStarts[j] = tempInt; - } - }; - sorter.quickSort(0, length - 1); + // sort readers and starts + SorterTemplate sorter = new SorterTemplate() { + protected int compare(int i, int j) { + int num1 = sortedSubReaders[i].numDocs(); + int num2 = sortedSubReaders[j].numDocs(); + if (num1 > num2) + return -1; + if (num1 < num2) + return 1; + return 0; + } + protected void swap(int i, int j) { + IndexReader temp = sortedSubReaders[i]; + sortedSubReaders[i] = sortedSubReaders[j]; + sortedSubReaders[j] = temp; + + int tempInt = sortedStarts[i]; + sortedStarts[i] = sortedStarts[j]; + sortedStarts[j] = tempInt; + } + }; + sorter.quickSort(0, length - 1); + } } /** Return the {@link IndexReader} this searches. */