Index: lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java =================================================================== --- lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (revision 1059811) +++ lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (working copy) @@ -150,8 +150,12 @@ } }; - /** Called whenever the running merges have changed, to - * pause & unpause threads. */ + /** + * Called whenever the running merges have changed, to pause & unpause + * threads. This method sorts the merge threads by their merge size in + * descending order and then pauses/unpauses threads from first to lsat -- + * that way, smaller merges are guaranteed to run before larger ones. + */ protected synchronized void updateMergeThreads() { // Only look at threads that are alive & not in the @@ -172,6 +176,7 @@ threadIdx++; } + // Sort the merge threads in descending order. CollectionUtil.mergeSort(activeMerges, compareByMergeDocCount); int pri = mergeThreadPriority; @@ -183,12 +188,8 @@ continue; } - final boolean doPause; - if (threadIdx < activeMergeCount-maxThreadCount) { - doPause = true; - } else { - doPause = false; - } + // pause the thread if maxThreadCount is smaller than the number of merge threads. + final boolean doPause = threadIdx < activeMergeCount - maxThreadCount; if (verbose()) { if (doPause != merge.getPause()) { @@ -213,13 +214,26 @@ } } - private boolean verbose() { + /** + * Returns true if verbosing is enabled. This method is usually used in + * conjunction with {@link #message(String)}, like that: + * + *
+   * if (verbose()) {
+   *   message("your message");
+   * }
+   * 
+ */ + protected boolean verbose() { return writer != null && writer.verbose(); } - private void message(String message) { - if (verbose()) - writer.message("CMS: " + message); + /** + * Outputs the given message - this method assumes {@link #verbose()} was + * called and returned true. + */ + protected void message(String message) { + writer.message("CMS: " + message); } private synchronized void initMergeThreadPriority() { @@ -240,10 +254,10 @@ /** Wait for any running merge threads to finish */ public void sync() { - while(true) { + while (true) { MergeThread toSync = null; - synchronized(this) { - for(MergeThread t : mergeThreads) { + synchronized (this) { + for (MergeThread t : mergeThreads) { if (t.isAlive()) { toSync = t; break; @@ -262,21 +276,20 @@ } } - private synchronized int mergeThreadCount() { + /** + * Returns the number of merge threads that are alive. Note that this number + * is ≤ {@link #mergeThreads} size. + */ + protected synchronized int mergeThreadCount() { int count = 0; - final int numThreads = mergeThreads.size(); - for(int i=0;i