Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 922587) +++ CHANGES.txt (working copy) @@ -167,6 +167,11 @@ * LUCENE-2247: Added a CharArrayMap for performance improvements in some stemmers and synonym filters. (Uwe Schindler) +* LUCENE-2293: Expose control over max number of threads that + IndexWriter will allow to run concurrently while indexing + documents (previously this was hardwired to 5), using + IndexWriterConfig.setMaxThreadStates. (Mike McCandless) + Optimizations * LUCENE-2075: Terms dict cache is now shared across threads instead Index: src/test/org/apache/lucene/index/TestIndexWriterConfig.java =================================================================== --- src/test/org/apache/lucene/index/TestIndexWriterConfig.java (revision 922587) +++ src/test/org/apache/lucene/index/TestIndexWriterConfig.java (working copy) @@ -98,6 +98,7 @@ getters.add("getMaxBufferedDocs"); getters.add("getIndexingChain"); getters.add("getMergedSegmentWarmer"); + getters.add("getMaxThreadStates"); 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/DocumentsWriter.java =================================================================== --- src/java/org/apache/lucene/index/DocumentsWriter.java (revision 922587) +++ src/java/org/apache/lucene/index/DocumentsWriter.java (working copy) @@ -125,7 +125,6 @@ // Max # ThreadState instances; if there are more threads // than this they share ThreadStates - private final static int MAX_THREAD_STATE = 5; private DocumentsWriterThreadState[] threadStates = new DocumentsWriterThreadState[0]; private final HashMap threadBindings = new HashMap(); @@ -141,6 +140,10 @@ int maxFieldLength = IndexWriterConfig.UNLIMITED_FIELD_LENGTH; Similarity similarity; + // max # simultaneous threads; if there are more than + // this, they wait for others to finish first + private final int maxThreadStates; + List newFiles; static class DocState { @@ -301,10 +304,11 @@ private boolean closed; - DocumentsWriter(Directory directory, IndexWriter writer, IndexingChain indexingChain) throws IOException { + DocumentsWriter(Directory directory, IndexWriter writer, IndexingChain indexingChain, int maxThreadStates) throws IOException { this.directory = directory; this.writer = writer; this.similarity = writer.getConfig().getSimilarity(); + this.maxThreadStates = maxThreadStates; flushedDocCount = writer.maxDoc(); consumer = indexingChain.getChain(this); @@ -721,7 +725,7 @@ if (minThreadState == null || ts.numThreads < minThreadState.numThreads) minThreadState = ts; } - if (minThreadState != null && (minThreadState.numThreads == 0 || threadStates.length >= MAX_THREAD_STATE)) { + if (minThreadState != null && (minThreadState.numThreads == 0 || threadStates.length >= maxThreadStates)) { state = minThreadState; state.numThreads++; } else { Index: src/java/org/apache/lucene/index/IndexWriter.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriter.java (revision 922587) +++ src/java/org/apache/lucene/index/IndexWriter.java (working copy) @@ -1153,7 +1153,7 @@ setRollbackSegmentInfos(segmentInfos); - docWriter = new DocumentsWriter(directory, this, conf.getIndexingChain()); + docWriter = new DocumentsWriter(directory, this, conf.getIndexingChain(), conf.getMaxThreadStates()); docWriter.setInfoStream(infoStream); docWriter.setMaxFieldLength(maxFieldLength); Index: src/java/org/apache/lucene/index/IndexWriterConfig.java =================================================================== --- src/java/org/apache/lucene/index/IndexWriterConfig.java (revision 922587) +++ src/java/org/apache/lucene/index/IndexWriterConfig.java (working copy) @@ -78,6 +78,12 @@ */ public static long WRITE_LOCK_TIMEOUT = 1000; + /** The maximum number of simultaneous threads that may be + * indexing documents at once in IndexWriter; if more + * than this many threads arrive they will wait for + * others to finish. */ + public final static int DEFAULT_MAX_THREAD_STATES = 8; + /** * Sets the default (for any instance) maximum time to wait for a write lock * (in milliseconds). @@ -110,6 +116,7 @@ private int maxBufferedDocs; private IndexingChain indexingChain; private IndexReaderWarmer mergedSegmentWarmer; + private int maxThreadStates; // required for clone private Version matchVersion; @@ -137,6 +144,7 @@ maxBufferedDocs = DEFAULT_MAX_BUFFERED_DOCS; indexingChain = DocumentsWriter.defaultIndexingChain; mergedSegmentWarmer = null; + maxThreadStates = DEFAULT_MAX_THREAD_STATES; } @Override @@ -483,7 +491,19 @@ return mergedSegmentWarmer; } + /** Sets the max number of simultaneous threads that may + * be indexing documents at once in IndexWriter. */ + public IndexWriterConfig setMaxThreadStates(int maxThreadStates) { + this.maxThreadStates = maxThreadStates; + return this; + } + /** Returns the max number of simultaneous threads that + * may be indexing documents at once in IndexWriter. */ + public int getMaxThreadStates() { + return maxThreadStates; + } + /** Expert: sets the {@link DocConsumer} chain to be used to process documents. */ IndexWriterConfig setIndexingChain(IndexingChain indexingChain) { this.indexingChain = indexingChain == null ? DocumentsWriter.defaultIndexingChain : indexingChain; @@ -513,6 +533,7 @@ sb.append("ramBufferSizeMB=").append(ramBufferSizeMB).append("\n"); sb.append("maxBufferedDocs=").append(maxBufferedDocs).append("\n"); sb.append("mergedSegmentWarmer=").append(mergedSegmentWarmer).append("\n"); + sb.append("maxThreadStates=").append(maxThreadStates).append("\n"); return sb.toString(); } }