lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikemcc...@apache.org
Subject svn commit: r619890 - /lucene/java/trunk/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
Date Fri, 08 Feb 2008 14:01:50 GMT
Author: mikemccand
Date: Fri Feb  8 06:01:48 2008
New Revision: 619890

URL: http://svn.apache.org/viewvc?rev=619890&view=rev
Log:
LUCENE-1164: when too many merge threads are running, pause until one or more finishes, instead
of doing the merge with the foreground thread

Modified:
    lucene/java/trunk/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java

Modified: lucene/java/trunk/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java?rev=619890&r1=619889&r2=619890&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java Fri Feb
 8 06:01:48 2008
@@ -25,10 +25,11 @@
 
 /** A {@link MergeScheduler} that runs each merge using a
  *  separate thread, up until a maximum number of threads
- *  ({@link #setMaxThreadCount}) at which points merges are
- *  run in the foreground, serially.  This is a simple way
- *  to use concurrency in the indexing process without
- *  having to create and manage application level
+ *  ({@link #setMaxThreadCount}) at which when a merge is
+ *  needed, the thread(s) that are updating the index will
+ *  pause until one or more merges completes.  This is a
+ *  simple way to use concurrency in the indexing process
+ *  without having to create and manage application level
  *  threads. */
 
 public class ConcurrentMergeScheduler extends MergeScheduler {
@@ -36,6 +37,8 @@
   private int mergeThreadPriority = -1;
 
   protected List mergeThreads = new ArrayList();
+
+  // Max number of threads allowed to be merging at once
   private int maxThreadCount = 3;
 
   private List exceptions = new ArrayList();
@@ -53,8 +56,9 @@
 
   /** Sets the max # simultaneous threads that may be
    *  running.  If a merge is necessary yet we already have
-   *  this many threads running, the merge is returned back
-   *  to IndexWriter so that it runs in the "foreground". */
+   *  this many threads running, the incoming thread (that
+   *  is calling add/updateDocument) will block until
+   *  a merge thread has completed. */
   public void setMaxThreadCount(int count) {
     if (count < 1)
       throw new IllegalArgumentException("count should be at least 1");
@@ -150,7 +154,7 @@
     message("  index: " + writer.segString());
 
     // Iterate, pulling from the IndexWriter's queue of
-    // pending merges, until its empty:
+    // pending merges, until it's empty:
     while(true) {
 
       // TODO: we could be careful about which merges to do in
@@ -167,27 +171,35 @@
       // deterministic assignment of segment names
       writer.mergeInit(merge);
 
-      message("  consider merge " + merge.segString(dir));
+      synchronized(this) {
+        while (mergeThreadCount() >= maxThreadCount) {
+          message("    too many merge threads running; stalling...");
+          try {
+            wait();
+          } catch (InterruptedException ie) {
+            Thread.currentThread().interrupt();
+          }
+        }
+
+        message("  consider merge " + merge.segString(dir));
       
-      if (merge.isExternal) {
-        message("    merge involves segments from an external directory; now run in foreground");
-      } else {
-        synchronized(this) {
-          if (mergeThreadCount() < maxThreadCount) {
-            // OK to spawn a new merge thread to handle this
-            // merge:
-            final MergeThread merger = getMergeThread(writer, merge);
-            mergeThreads.add(merger);
-            message("    launch new thread [" + merger.getName() + "]");
-            merger.start();
-            continue;
-          } else
-            message("    too many merge threads running; run merge in foreground");
+        if (merge.isExternal) {
+          message("    merge involves segments from an external directory; now run in foreground");
+        } else {
+          assert mergeThreadCount() < maxThreadCount;
+
+          // OK to spawn a new merge thread to handle this
+          // merge:
+          final MergeThread merger = getMergeThread(writer, merge);
+          mergeThreads.add(merger);
+          message("    launch new thread [" + merger.getName() + "]");
+          merger.start();
+          continue;
         }
       }
 
-      // Too many merge threads already running, so we do
-      // this in the foreground of the calling thread
+      // This merge involves segments outside our index
+      // Directory so we must merge in foreground
       doMerge(merge);
     }
   }
@@ -285,7 +297,8 @@
         }
       } finally {
         synchronized(ConcurrentMergeScheduler.this) {
-          mergeThreads.remove(this);
+          boolean removed = mergeThreads.remove(this);
+          assert removed;
           ConcurrentMergeScheduler.this.notifyAll();
         }
       }



Mime
View raw message