Index: src/test/org/apache/lucene/search/TestTopDocsCollector.java =================================================================== --- src/test/org/apache/lucene/search/TestTopDocsCollector.java (revision 962932) +++ src/test/org/apache/lucene/search/TestTopDocsCollector.java (working copy) @@ -30,7 +30,7 @@ public class TestTopDocsCollector extends LuceneTestCase { - private static final class MyTopsDocCollector extends TopDocsCollector { + private static final class MyTopsDocCollector extends TopDocsCollector { private int idx = 0; private int base = 0; @@ -207,4 +207,46 @@ } } + public void testSubclassWithoutPQ() throws IOException { + final TopDocs mtd = new TopDocs( 77, new ScoreDoc[0] ); + + // this is a completely bogus TDC just showing that PQ can be null and we can override + // methods that were previously final + TopDocsCollector tdc = new TopDocsCollector(null) { + @Override + public boolean acceptsDocsOutOfOrder() { + return true; + } + @Override + public void collect(int doc) throws IOException { + ++totalHits; + } + @Override + public void setNextReader(IndexReader reader, int docBase) throws IOException { + } + @Override + public void setScorer(Scorer scorer) throws IOException { + } + @Override + public TopDocs topDocs() { + return mtd; + } + @Override + public TopDocs topDocs(int start) { + return mtd; + } + @Override + public TopDocs topDocs(int start, int end) { + return mtd; + } + }; + + Query q = new MatchAllDocsQuery(); + IndexSearcher searcher = new IndexSearcher(dir, true); + searcher.search(q, tdc); + searcher.close(); + assertEquals(30, tdc.getTotalHits()); + assertEquals(77, tdc.topDocs().totalHits); + } + } Index: src/java/org/apache/lucene/search/TopDocsCollector.java =================================================================== --- src/java/org/apache/lucene/search/TopDocsCollector.java (revision 962932) +++ src/java/org/apache/lucene/search/TopDocsCollector.java (working copy) @@ -25,8 +25,10 @@ * collector allows easy extension by providing a single constructor which * accepts a {@link PriorityQueue} as well as protected members for that * priority queue and a counter of the number of total hits.
- * Extending classes can override {@link #topDocs(int, int)} and - * {@link #getTotalHits()} in order to provide their own implementation. + * Most extending classes can override {@link #newTopDocs(ScoreDoc[], int)} and + * {@link #populateResults(ScoreDoc[], int)} in order to provide their own + * implementation. Subclasses may completely change behavior by overridding the + * various topDocs() methods etc. */ public abstract class TopDocsCollector extends Collector { @@ -45,12 +47,17 @@ /** The total number of documents that the collector encountered. */ protected int totalHits; + /** + * construct with a {@link PriorityQueue}, may be null. If you plan to implement + * without using a pq, you must override ALL public methods. + * @param pq + */ protected TopDocsCollector(PriorityQueue pq) { this.pq = pq; } /** - * Populates the results array with the ScoreDoc instaces. This can be + * Populates the results array with the ScoreDoc instances. This can be * overridden in case a different ScoreDoc type should be returned. */ protected void populateResults(ScoreDoc[] results, int howMany) { @@ -75,7 +82,7 @@ } /** Returns the top docs that were collected by this collector. */ - public final TopDocs topDocs() { + public TopDocs topDocs() { // In case pq was populated with sentinel values, there might be less // results than pq.size(). Therefore return all results until either // pq.size() or totalHits. @@ -94,7 +101,7 @@ * with the returned {@link TopDocs} object, which will contain all the * results this search execution collected. */ - public final TopDocs topDocs(int start) { + public TopDocs topDocs(int start) { // In case pq was populated with sentinel values, there might be less // results than pq.size(). Therefore return all results until either // pq.size() or totalHits. @@ -115,7 +122,7 @@ * returned {@link TopDocs} object, which will contain all the results this * search execution collected. */ - public final TopDocs topDocs(int start, int howMany) { + public TopDocs topDocs(int start, int howMany) { // In case pq was populated with sentinel values, there might be less // results than pq.size(). Therefore return all results until either