Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 950226) +++ lucene/CHANGES.txt (working copy) @@ -455,6 +455,11 @@ * LUCENE-2424: Fix FieldDoc.toString to not just fallback to super.toString() (Stephen Green via Mike McCandless) +* LUCENE-2311: Always pass a "fully loaded" (terms index & doc stores) + SegmentsReader to IndexWriter's mergedSegmentWarmer (if set), so + that warming is free to do whatever it needs to. (Earwin Burrfoot + via Mike McCandless) + New features * LUCENE-2128: Parallelized fetching document frequencies during weight Index: lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java =================================================================== --- lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java (revision 950226) +++ lucene/src/test/org/apache/lucene/index/TestIndexWriterReader.java (working copy) @@ -32,6 +32,7 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.MockRAMDirectory; import org.apache.lucene.store.AlreadyClosedException; @@ -840,4 +841,25 @@ w.close(); } + public void testSegmentWarmer() throws Exception { + Directory dir = new MockRAMDirectory(); + IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()) + .setMaxBufferedDocs(2).setReaderPooling(true)); + w.setMergedSegmentWarmer(new IndexWriter.IndexReaderWarmer() { + public void warm(IndexReader r) throws IOException { + final IndexSearcher s = new IndexSearcher(r); + final TopDocs hits = s.search(new TermQuery(new Term("foo", "bar")), 10); + assertEquals(20, hits.totalHits); + } + }); + + Document doc = new Document(); + doc.add(new Field("foo", "bar", Field.Store.YES, Field.Index.NOT_ANALYZED)); + for(int i=0;i<20;i++) { + w.addDocument(doc); + } + w.waitForMerges(); + w.close(); + dir.close(); + } } Index: lucene/src/test/org/apache/lucene/util/LuceneTestCase.java =================================================================== --- lucene/src/test/org/apache/lucene/util/LuceneTestCase.java (revision 950226) +++ lucene/src/test/org/apache/lucene/util/LuceneTestCase.java (working copy) @@ -129,7 +129,18 @@ @Override protected void tearDown() throws Exception { BooleanQuery.setMaxClauseCount(savedBoolMaxClauseCount); + try { + Thread.setDefaultUncaughtExceptionHandler(savedUncaughtExceptionHandler); + if (!uncaughtExceptions.isEmpty()) { + System.err.println("The following exceptions were thrown by threads:"); + for (UncaughtExceptionEntry entry : uncaughtExceptions) { + System.err.println("*** Thread: " + entry.thread.getName() + " ***"); + entry.exception.printStackTrace(System.err); + } + fail("Some threads threw uncaught exceptions!"); + } + // this isn't as useful as calling directly from the scope where the // index readers are used, because they could be gc'ed just before // tearDown is called. @@ -145,17 +156,7 @@ } finally { purgeFieldCache(FieldCache.DEFAULT); } - - Thread.setDefaultUncaughtExceptionHandler(savedUncaughtExceptionHandler); - if (!uncaughtExceptions.isEmpty()) { - System.err.println("The following exceptions were thrown by threads:"); - for (UncaughtExceptionEntry entry : uncaughtExceptions) { - System.err.println("*** Thread: " + entry.thread.getName() + " ***"); - entry.exception.printStackTrace(System.err); - } - fail("Some threads throwed uncaught exceptions!"); - } - + super.tearDown(); } Index: lucene/src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- lucene/src/java/org/apache/lucene/index/IndexWriter.java (revision 950226) +++ lucene/src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -4033,7 +4033,21 @@ // keep deletes (it's costly to open entire reader // when we just need deletes) - final SegmentReader mergedReader = readerPool.get(merge.info, false, BufferedIndexInput.BUFFER_SIZE, -1); + final int termsIndexDivisor; + final boolean loadDocStores; + + if (poolReaders && mergedSegmentWarmer != null) { + // Load terms index & doc stores so the segment + // warmer can run searches, load documents/term + // vectors + termsIndexDivisor = 1; + loadDocStores = true; + } else { + termsIndexDivisor = -1; + loadDocStores = false; + } + + final SegmentReader mergedReader = readerPool.get(merge.info, loadDocStores, BufferedIndexInput.BUFFER_SIZE, termsIndexDivisor); try { if (poolReaders && mergedSegmentWarmer != null) { mergedSegmentWarmer.warm(mergedReader);