LUCENE-1483: add expert IndexSearcher ctor to search sub-readers in natural order (vs default sort-by-numDocs order)

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@740021 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2009-02-02 16:21:49 +00:00
parent e7edb24bc0
commit 62d56d9410
2 changed files with 93 additions and 27 deletions

View File

@ -48,7 +48,7 @@ public class IndexSearcher extends Searcher {
* @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 @@ public class IndexSearcher extends Searcher {
* @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 numDocs(); 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 @@ public class IndexSearcher extends Searcher {
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 @@ public class IndexSearcher extends Searcher {
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. */

View File

@ -40,8 +40,10 @@ import org.apache.lucene.document.FieldSelector;
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 @@ public class TestIndexReader extends LuceneTestCase
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();
}
}