You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by mi...@apache.org on 2008/09/15 16:26:27 UTC

svn commit: r695483 - in /lucene/java/branches/lucene_2_3: CHANGES.txt src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java src/java/org/apache/lucene/index/IndexWriter.java src/test/org/apache/lucene/index/TestIndexWriter.java

Author: mikemccand
Date: Mon Sep 15 07:26:26 2008
New Revision: 695483

URL: http://svn.apache.org/viewvc?rev=695483&view=rev
Log:
LUCENE-1384: fix intermittant bug in ConcurrentMergeScheduler that can cause 'segment XXX exists in external directory yet the MergeScheduler executed the merge in a separate thread' exceptions during IndexWriter.addIndexesNoOptimize

Modified:
    lucene/java/branches/lucene_2_3/CHANGES.txt
    lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
    lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/IndexWriter.java
    lucene/java/branches/lucene_2_3/src/test/org/apache/lucene/index/TestIndexWriter.java

Modified: lucene/java/branches/lucene_2_3/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_3/CHANGES.txt?rev=695483&r1=695482&r2=695483&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_3/CHANGES.txt (original)
+++ lucene/java/branches/lucene_2_3/CHANGES.txt Mon Sep 15 07:26:26 2008
@@ -49,6 +49,12 @@
 13. LUCENE-1347: Fixed hang in IndexWriter.abort() if it was called
     again after previously hitting an exception during a prior call.
     (Mike McCandless)
+
+14. LUCENE-1384: Fixed intermittant "segment XXX exists in external
+    directory yet the MergeScheduler executed the merge in a separate
+    thread" exception from being thrown by
+    IndexWriter.addIndexesNoOptimize when using
+    ConcurrentMergeScheduler.  (Anthony Urso via Mike McCandless)
 	
 Build
 

Modified: lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java?rev=695483&r1=695482&r2=695483&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java (original)
+++ lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java Mon Sep 15 07:26:26 2008
@@ -241,7 +241,7 @@
 
           // Subsequent times through the loop we do any new
           // merge that writer says is necessary:
-          merge = writer.getNextMerge();
+          merge = writer.getNextMerge(false);
           if (merge != null) {
             writer.mergeInit(merge);
             message("  merge thread: do another merge " + merge.segString(dir));

Modified: lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/IndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/IndexWriter.java?rev=695483&r1=695482&r2=695483&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/IndexWriter.java (original)
+++ lucene/java/branches/lucene_2_3/src/java/org/apache/lucene/index/IndexWriter.java Mon Sep 15 07:26:26 2008
@@ -1778,6 +1778,12 @@
           } catch (InterruptedException ie) {
           }
 
+          // Since we may have external segments in the
+          // index, which CMS BG threads can't touch, we
+          // need to give FG thread a chance to run merges
+          // here:
+          maybeMerge(maxNumSegments, true);
+
           if (mergeExceptions.size() > 0) {
             // Forward any exceptions in background merge
             // threads to the current thread:
@@ -1871,18 +1877,31 @@
 
   /** Expert: the {@link MergeScheduler} calls this method
    *  to retrieve the next merge requested by the
-   *  MergePolicy */
-  synchronized MergePolicy.OneMerge getNextMerge() {
+   *  MergePolicy.  If allowExternal is true then any
+   *  pending merge may be returned; else, only merges not
+   *  involving external segments may be returned. */
+  synchronized MergePolicy.OneMerge getNextMerge(boolean allowExternal) {
     if (pendingMerges.size() == 0)
       return null;
     else {
-      // Advance the merge from pending to running
-      MergePolicy.OneMerge merge = (MergePolicy.OneMerge) pendingMerges.removeFirst();
-      runningMerges.add(merge);
-      return merge;
+      Iterator it = pendingMerges.iterator();
+      while(it.hasNext()) {
+        MergePolicy.OneMerge merge = (MergePolicy.OneMerge) it.next();
+        if (allowExternal || !merge.isExternal) {
+          // Advance the merge from pending to running
+          it.remove();
+          runningMerges.add(merge);
+          return merge;
+        }
+      }
+      return null;
     }
   }
 
+  synchronized MergePolicy.OneMerge getNextMerge() {
+    return getNextMerge(true);
+  }
+
   /*
    * Begin a transaction.  During a transaction, any segment
    * merges that happen (or ram segments flushed) will not

Modified: lucene/java/branches/lucene_2_3/src/test/org/apache/lucene/index/TestIndexWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/branches/lucene_2_3/src/test/org/apache/lucene/index/TestIndexWriter.java?rev=695483&r1=695482&r2=695483&view=diff
==============================================================================
--- lucene/java/branches/lucene_2_3/src/test/org/apache/lucene/index/TestIndexWriter.java (original)
+++ lucene/java/branches/lucene_2_3/src/test/org/apache/lucene/index/TestIndexWriter.java Mon Sep 15 07:26:26 2008
@@ -2804,8 +2804,8 @@
       super(dir, new StandardAnalyzer());
       myDir = dir;
     }
-    synchronized MergePolicy.OneMerge getNextMerge() {
-      MergePolicy.OneMerge merge = super.getNextMerge();
+    synchronized MergePolicy.OneMerge getNextMerge(boolean allowExternal) {
+      MergePolicy.OneMerge merge = super.getNextMerge(allowExternal);
       if (merge != null)
         mergeCount++;
       return merge;