You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2011/11/08 23:38:05 UTC

svn commit: r1199503 - in /lucene/dev/branches/lucene2621: ./ dev-tools/idea/lucene/contrib/ lucene/ lucene/contrib/misc/src/java/org/apache/lucene/search/ lucene/contrib/misc/src/test/org/apache/lucene/index/ lucene/contrib/sandbox/src/test/org/apache...

Author: rmuir
Date: Tue Nov  8 22:38:04 2011
New Revision: 1199503

URL: http://svn.apache.org/viewvc?rev=1199503&view=rev
Log:
LUCENE-2621: merge trunk (1199391:1199501)

Modified:
    lucene/dev/branches/lucene2621/   (props changed)
    lucene/dev/branches/lucene2621/dev-tools/idea/lucene/contrib/   (props changed)
    lucene/dev/branches/lucene2621/lucene/   (props changed)
    lucene/dev/branches/lucene2621/lucene/contrib/misc/src/java/org/apache/lucene/search/SearcherManager.java
    lucene/dev/branches/lucene2621/lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java
    lucene/dev/branches/lucene2621/lucene/contrib/sandbox/src/test/org/apache/lucene/sandbox/queries/regex/TestSpanRegexQuery.java   (props changed)
    lucene/dev/branches/lucene2621/lucene/src/java/org/apache/lucene/index/codecs/lucene3x/TermInfosReaderIndex.java   (props changed)
    lucene/dev/branches/lucene2621/modules/queryparser/src/test/org/apache/lucene/queryparser/xml/builders/TestNumericRangeFilterBuilder.java   (props changed)
    lucene/dev/branches/lucene2621/solr/   (props changed)
    lucene/dev/branches/lucene2621/solr/CHANGES.txt   (props changed)
    lucene/dev/branches/lucene2621/solr/LICENSE.txt   (props changed)
    lucene/dev/branches/lucene2621/solr/NOTICE.txt   (props changed)
    lucene/dev/branches/lucene2621/solr/README.txt   (props changed)
    lucene/dev/branches/lucene2621/solr/build.xml   (props changed)
    lucene/dev/branches/lucene2621/solr/client/   (props changed)
    lucene/dev/branches/lucene2621/solr/common-build.xml   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/clustering/src/test-files/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/dataimporthandler-extras/src/java/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/dataimporthandler/src/java/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/dataimporthandler/src/test-files/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/dataimporthandler/src/test/org/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/uima/src/java/   (props changed)
    lucene/dev/branches/lucene2621/solr/contrib/uima/src/test-files/   (props changed)
    lucene/dev/branches/lucene2621/solr/core/   (props changed)
    lucene/dev/branches/lucene2621/solr/core/src/java/   (props changed)
    lucene/dev/branches/lucene2621/solr/core/src/test/   (props changed)
    lucene/dev/branches/lucene2621/solr/dev-tools/   (props changed)
    lucene/dev/branches/lucene2621/solr/example/   (props changed)
    lucene/dev/branches/lucene2621/solr/lib/   (props changed)
    lucene/dev/branches/lucene2621/solr/scripts/   (props changed)
    lucene/dev/branches/lucene2621/solr/site/   (props changed)
    lucene/dev/branches/lucene2621/solr/site-src/   (props changed)
    lucene/dev/branches/lucene2621/solr/solrj/   (props changed)
    lucene/dev/branches/lucene2621/solr/solrj/src/java/   (props changed)
    lucene/dev/branches/lucene2621/solr/solrj/src/test/org/apache/solr/client/   (props changed)
    lucene/dev/branches/lucene2621/solr/solrj/src/test/org/apache/solr/client/solrj/   (props changed)
    lucene/dev/branches/lucene2621/solr/solrj/src/test/org/apache/solr/common/   (props changed)
    lucene/dev/branches/lucene2621/solr/test-framework/   (props changed)
    lucene/dev/branches/lucene2621/solr/testlogging.properties   (props changed)
    lucene/dev/branches/lucene2621/solr/webapp/   (props changed)

Modified: lucene/dev/branches/lucene2621/lucene/contrib/misc/src/java/org/apache/lucene/search/SearcherManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2621/lucene/contrib/misc/src/java/org/apache/lucene/search/SearcherManager.java?rev=1199503&r1=1199502&r2=1199503&view=diff
==============================================================================
--- lucene/dev/branches/lucene2621/lucene/contrib/misc/src/java/org/apache/lucene/search/SearcherManager.java (original)
+++ lucene/dev/branches/lucene2621/lucene/contrib/misc/src/java/org/apache/lucene/search/SearcherManager.java Tue Nov  8 22:38:04 2011
@@ -147,7 +147,8 @@ public final class SearcherManager {
    * </p>
    * 
    * <p>
-   * This method returns true if a new reader was in fact opened.
+   * This method returns true if a new reader was in fact opened or 
+   * if the current searcher has no pending changes.
    * </p>
    */
   public boolean maybeReopen() throws IOException {
@@ -173,10 +174,8 @@ public final class SearcherManager {
               release(newSearcher);
             }
           }
-          return true;
-        } else {
-          return false;
         }
+        return true;
       } finally {
         reopenLock.release();
       }
@@ -184,7 +183,7 @@ public final class SearcherManager {
       return false;
     }
   }
-
+  
   /**
    * Returns <code>true</code> if no changes have occured since this searcher
    * ie. reader was opened, otherwise <code>false</code>.
@@ -251,4 +250,5 @@ public final class SearcherManager {
     currentSearcher = newSearcher;
     release(oldSearcher);
   }
+ 
 }

Modified: lucene/dev/branches/lucene2621/lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene2621/lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java?rev=1199503&r1=1199502&r2=1199503&view=diff
==============================================================================
--- lucene/dev/branches/lucene2621/lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java (original)
+++ lucene/dev/branches/lucene2621/lucene/contrib/misc/src/test/org/apache/lucene/index/TestNRTManager.java Tue Nov  8 22:38:04 2011
@@ -19,15 +19,24 @@ package org.apache.lucene.index;
 
 import java.io.IOException;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.TextField;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.SearcherManager;
 import org.apache.lucene.search.SearcherWarmer;
 import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.LockObtainFailedException;
 import org.apache.lucene.store.NRTCachingDirectory;
+import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase.UseNoMemoryExpensiveCodec;
+import org.apache.lucene.util.ThreadInterruptedException;
 
 @UseNoMemoryExpensiveCodec
 public class TestNRTManager extends ThreadedIndexingAndSearchingTestCase {
@@ -244,4 +253,100 @@ public class TestNRTManager extends Thre
     nrtThread.close();
     nrt.close();
   }
+  
+  /*
+   * LUCENE-3528 - NRTManager hangs in certain situations 
+   */
+  public void testThreadStarvationNoDeleteNRTReader() throws IOException, InterruptedException {
+    IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random));
+    Directory d = newDirectory();
+    final CountDownLatch latch = new CountDownLatch(1);
+    final CountDownLatch signal = new CountDownLatch(1);
+
+    LatchedIndexWriter writer = new LatchedIndexWriter(d, conf, latch, signal);
+    final NRTManager manager = new NRTManager(writer, null, null, false);
+    Document doc = new Document();
+    doc.add(newField("test","test", TextField.TYPE_STORED));
+    long gen = manager.addDocument(doc);
+    assertTrue(manager.maybeReopen(false));
+    assertFalse(gen < manager.getCurrentSearchingGen(false));
+    Thread t = new Thread() {
+      public void run() {
+        try {
+          signal.await();
+          assertTrue(manager.maybeReopen(false));
+          manager.deleteDocuments(new TermQuery(new Term("foo", "barista")));
+          manager.maybeReopen(false); // kick off another reopen so we inc. the internal gen
+        } catch (Exception e) {
+          e.printStackTrace();
+        } finally {
+          latch.countDown(); // let the add below finish
+        }
+      }
+    };
+    t.start();
+    writer.waitAfterUpdate = true; // wait in addDocument to let some reopens go through
+    final long lastGen = manager.updateDocument(new Term("foo", "bar"), doc); // once this returns the doc is already reflected in the last reopen
+    assertFalse(manager.getSearcherManager(false).isSearcherCurrent()); // false since there is a delete in the queue
+    
+    IndexSearcher acquire = manager.getSearcherManager(false).acquire();
+    try {
+      assertEquals(2, acquire.getIndexReader().numDocs());
+    } finally {
+      acquire.getIndexReader().decRef();
+    }
+    NRTManagerReopenThread thread = new NRTManagerReopenThread(manager, 0.01, 0.01);
+    thread.start(); // start reopening
+    if (VERBOSE) {
+      System.out.println("waiting now for generation " + lastGen);
+    }
+    
+    final AtomicBoolean finished = new AtomicBoolean(false);
+    Thread waiter = new Thread() {
+      public void run() {
+        manager.waitForGeneration(lastGen, false);
+        finished.set(true);
+      }
+    };
+    waiter.start();
+    manager.maybeReopen(false);
+    waiter.join(1000);
+    if (!finished.get()) {
+      waiter.interrupt();
+      fail("thread deadlocked on waitForGeneration");
+    }
+    thread.close();
+    thread.join();
+    IOUtils.close(manager, writer, d);
+  }
+  
+  public static class LatchedIndexWriter extends IndexWriter {
+
+    private CountDownLatch latch;
+    boolean waitAfterUpdate = false;
+    private CountDownLatch signal;
+
+    public LatchedIndexWriter(Directory d, IndexWriterConfig conf,
+        CountDownLatch latch, CountDownLatch signal)
+        throws CorruptIndexException, LockObtainFailedException, IOException {
+      super(d, conf);
+      this.latch = latch;
+      this.signal = signal;
+
+    }
+
+    public void updateDocument(Term term,
+        Iterable<? extends IndexableField> doc, Analyzer analyzer)
+        throws CorruptIndexException, IOException {
+      super.updateDocument(term, doc, analyzer);
+      try {
+        if (waitAfterUpdate) {
+          signal.countDown();
+          latch.await();
+        }
+      } catch (InterruptedException e) {
+        throw new ThreadInterruptedException(e);
+      }
+    }
+  }
 }