Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 923242) +++ CHANGES.txt (working copy) @@ -177,6 +177,10 @@ documents (previously this was hardwired to 5), using IndexWriterConfig.setMaxThreadStates. (Mike McCandless) +* LUCENE-2297: Enable turning on reader pooling inside IndexWriter + even when getReader (near-real-timer reader) is not in use, through + IndexWriterConfig.enable/disableReaderPooling. (Mike McCandless) + Optimizations * LUCENE-2075: Terms dict cache is now shared across threads instead Index: src/test/org/apache/lucene/index/TestStressIndexing2.java =================================================================== --- src/test/org/apache/lucene/index/TestStressIndexing2.java (revision 923242) +++ src/test/org/apache/lucene/index/TestStressIndexing2.java (working copy) @@ -85,7 +85,8 @@ Directory dir2 = new MockRAMDirectory(); // mergeFactor=2; maxBufferedDocs=2; Map docs = indexRandom(1, 3, 2, dir1); int maxThreadStates = 1+r.nextInt(10); - Map docs = indexRandom(10, 10, 100, dir1, maxThreadStates); + boolean doReaderPooling = r.nextBoolean(); + Map docs = indexRandom(10, 10, 100, dir1, maxThreadStates, doReaderPooling); indexSerial(docs, dir2); // verifying verify @@ -103,6 +104,7 @@ mergeFactor=r.nextInt(3)+2; maxBufferedDocs=r.nextInt(3)+2; int maxThreadStates = 1+r.nextInt(10); + boolean doReaderPooling = r.nextBoolean(); seed++; int nThreads=r.nextInt(5)+1; @@ -110,7 +112,7 @@ int range=r.nextInt(20)+1; Directory dir1 = new MockRAMDirectory(); Directory dir2 = new MockRAMDirectory(); - Map docs = indexRandom(nThreads, iter, range, dir1, maxThreadStates); + Map docs = indexRandom(nThreads, iter, range, dir1, maxThreadStates, doReaderPooling); indexSerial(docs, dir2); verifyEquals(dir1, dir2, "id"); } @@ -184,12 +186,14 @@ return dw; } - public Map indexRandom(int nThreads, int iterations, int range, Directory dir, int maxThreadStates) throws IOException, InterruptedException { + public Map indexRandom(int nThreads, int iterations, int range, Directory dir, int maxThreadStates, + boolean doReaderPooling) throws IOException, InterruptedException { Map docs = new HashMap(); for(int iter=0;iter<3;iter++) { IndexWriter w = new MockIndexWriter(dir, new IndexWriterConfig( TEST_VERSION_CURRENT, new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).setOpenMode(OpenMode.CREATE) - .setRAMBufferSizeMB(0.1).setMaxBufferedDocs(maxBufferedDocs).setMaxThreadStates(maxThreadStates)); + .setRAMBufferSizeMB(0.1).setMaxBufferedDocs(maxBufferedDocs).setMaxThreadStates(maxThreadStates) + .setReaderPooling(doReaderPooling)); LogMergePolicy lmp = (LogMergePolicy) w.getMergePolicy(); lmp.setUseCompoundFile(false); lmp.setUseCompoundDocStore(false); Index: src/test/org/apache/lucene/index/TestIndexWriterConfig.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriterConfig.java (revision 923242) +++ src/test/org/apache/lucene/index/TestIndexWriterConfig.java (working copy) @@ -99,6 +99,7 @@ getters.add("getIndexingChain"); getters.add("getMergedSegmentWarmer"); getters.add("getMaxThreadStates"); + getters.add("getReaderPooling"); for (Method m : IndexWriterConfig.class.getDeclaredMethods()) { if (m.getDeclaringClass() == IndexWriterConfig.class && m.getName().startsWith("get")) { assertTrue("method " + m.getName() + " is not tested for defaults", getters.contains(m.getName())); Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 923242) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -1079,7 +1079,8 @@ similarity = conf.getSimilarity(); mergeScheduler = conf.getMergeScheduler(); mergedSegmentWarmer = conf.getMergedSegmentWarmer(); - + poolReaders = conf.getReaderPooling(); + OpenMode mode = conf.getOpenMode(); boolean create; if (mode == OpenMode.CREATE) { Index: src/java/org/apache/lucene/index/IndexWriterConfig.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriterConfig.java (revision 923242) +++ src/java/org/apache/lucene/index/IndexWriterConfig.java (working copy) @@ -117,6 +117,7 @@ private IndexingChain indexingChain; private IndexReaderWarmer mergedSegmentWarmer; private int maxThreadStates; + private boolean readerPooling; // required for clone private Version matchVersion; @@ -504,6 +505,25 @@ return maxThreadStates; } + /** By default, IndexWriter does not pool the + * SegmentReaders it must open for deletions and + * merging, unless a near-real-time reader has been + * obtained by calling {@link IndexWriter#getReader}. + * This method lets you enable pooling without getting a + * near-real-time reader. NOTE: if you set this to + * false, IndexWriter will still pool readers once + * {@link IndexWriter#getReader} is called. */ + public IndexWriterConfig setReaderPooling(boolean readerPooling) { + this.readerPooling = readerPooling; + return this; + } + + /** Returns true if IndexWriter should pool readers even + * if {@link IndexWriter#getReader} has not been called. */ + public boolean getReaderPooling() { + return readerPooling; + } + /** Expert: sets the {@link DocConsumer} chain to be used to process documents. */ IndexWriterConfig setIndexingChain(IndexingChain indexingChain) { this.indexingChain = indexingChain == null ? DocumentsWriter.defaultIndexingChain : indexingChain; @@ -534,6 +554,7 @@ sb.append("maxBufferedDocs=").append(maxBufferedDocs).append("\n"); sb.append("mergedSegmentWarmer=").append(mergedSegmentWarmer).append("\n"); sb.append("maxThreadStates=").append(maxThreadStates).append("\n"); + sb.append("readerPooling=").append(readerPooling).append("\n"); return sb.toString(); } }