You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2012/02/17 20:30:07 UTC
svn commit: r1245720 - in /lucene/dev/branches/branch_3x: ./ lucene/
lucene/core/src/java/org/apache/lucene/search/
lucene/core/src/test/org/apache/lucene/search/
Author: mikemccand
Date: Fri Feb 17 19:30:06 2012
New Revision: 1245720
URL: http://svn.apache.org/viewvc?rev=1245720&view=rev
Log:
LUCENE-3776: now you acquire/release directly from NRTManager (fixes trap)
Modified:
lucene/dev/branches/branch_3x/ (props changed)
lucene/dev/branches/branch_3x/lucene/ (props changed)
lucene/dev/branches/branch_3x/lucene/CHANGES.txt
lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManager.java
lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManagerReopenThread.java
lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java
lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/SearcherManager.java
lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestNRTManager.java
lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestSearcherManager.java
Modified: lucene/dev/branches/branch_3x/lucene/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/CHANGES.txt?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/CHANGES.txt (original)
+++ lucene/dev/branches/branch_3x/lucene/CHANGES.txt Fri Feb 17 19:30:06 2012
@@ -120,6 +120,9 @@ API Changes
method maybeReopen has been deprecated in favor of maybeRefresh().
(Shai Erera, Mike McCandless, Simon Willnauer)
+* LUCENE-3776: You now acquire/release the IndexSearcher directly from
+ NRTManager. (Mike McCandless)
+
New Features
* LUCENE-3593: Added a FieldValueFilter that accepts all documents that either
Modified: lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManager.java?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManager.java (original)
+++ lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManager.java Fri Feb 17 19:30:06 2012
@@ -17,7 +17,6 @@ package org.apache.lucene.search;
* limitations under the License.
*/
-import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
@@ -52,13 +51,11 @@ import org.apache.lucene.util.ThreadInte
* not. In this case you should use a single {@link
* NRTManager.TrackingIndexWriter} instance for both.
*
- * <p>Then, use {@link #getSearcherManager} to obtain the
- * {@link SearcherManager} that you then use to
- * acquire/release searchers. Don't call maybeReopen on
- * that SearcherManager! Only call NRTManager's {@link
- * #maybeReopen}.
+ * <p>Then, use {@link #acquire} to obtain the
+ * {@link IndexSearcher}, and {@link #release} (ideally,
+ * from within a <code>finally</code> clause) to release it.
*
- * <p>NOTE: to use this class, you must call {@link #maybeReopen()}
+ * <p>NOTE: to use this class, you must call {@link #maybeRefresh()}
* periodically. The {@link NRTManagerReopenThread} is a
* simple class to do this on a periodic basis, and reopens
* more quickly if a request is waiting. If you implement
@@ -72,14 +69,14 @@ import org.apache.lucene.util.ThreadInte
* @lucene.experimental
*/
-public class NRTManager implements Closeable {
+public class NRTManager extends ReferenceManager<IndexSearcher> {
private static final long MAX_SEARCHER_GEN = Long.MAX_VALUE;
private final TrackingIndexWriter writer;
private final List<WaitingListener> waitingListeners = new CopyOnWriteArrayList<WaitingListener>();
- private final ReentrantLock reopenLock = new ReentrantLock();
- private final Condition newGeneration = reopenLock.newCondition();
+ private final ReentrantLock genLock = new ReentrantLock();;
+ private final Condition newGeneration = genLock.newCondition();
+ private final SearcherFactory searcherFactory;
- private final SearcherManager mgr;
private volatile long searchingGen;
/**
@@ -102,24 +99,25 @@ public class NRTManager implements Close
* apply deletes. This is useful for cases where certain
* uses can tolerate seeing some deleted docs, since
* reopen time is faster if deletes need not be applied. */
- public NRTManager(TrackingIndexWriter writer, SearcherFactory searcherFactory, boolean applyDeletes) throws IOException {
+ public NRTManager(TrackingIndexWriter writer, SearcherFactory searcherFactory, boolean applyAllDeletes) throws IOException {
this.writer = writer;
- mgr = new SearcherManager(writer.getIndexWriter(), applyDeletes, searcherFactory);
+ if (searcherFactory == null) {
+ searcherFactory = new SearcherFactory();
+ }
+ this.searcherFactory = searcherFactory;
+ current = SearcherManager.getSearcher(searcherFactory, IndexReader.open(writer.getIndexWriter(), applyAllDeletes));
}
- /**
- * Returns the {@link SearcherManager} you should use to
- * acquire/release searchers.
- *
- * <p><b>NOTE</b>: Never call maybeReopen on the returned
- * SearcherManager; only call this NRTManager's {@link
- * #maybeReopen}. Otherwise threads waiting for a
- * generation may never return.
- */
- public SearcherManager getSearcherManager() {
- return mgr;
+ @Override
+ protected void decRef(IndexSearcher reference) throws IOException {
+ reference.getIndexReader().decRef();
}
+ @Override
+ protected boolean tryIncRef(IndexSearcher reference) {
+ return reference.getIndexReader().tryIncRef();
+ }
+
/** NRTManager invokes this interface to notify it when a
* caller is waiting for a specific generation searcher
* to be visible. */
@@ -265,7 +263,7 @@ public class NRTManager implements Close
* If the current searcher is older than the
* target generation, this method will block
* until the searcher is reopened, by another via
- * {@link #maybeReopen} or until the {@link NRTManager} is closed.
+ * {@link #maybeRefresh} or until the {@link NRTManager} is closed.
*
* @param targetGen the generation to wait for
*/
@@ -278,7 +276,7 @@ public class NRTManager implements Close
* the searcher. If the current searcher is older than
* the target generation, this method will block until the
* searcher has been reopened by another thread via
- * {@link #maybeReopen}, the given waiting time has elapsed, or until
+ * {@link #maybeRefresh}, the given waiting time has elapsed, or until
* the NRTManager is closed.
* <p>
* NOTE: if the waiting time elapses before the requested target generation is
@@ -297,7 +295,7 @@ public class NRTManager implements Close
if (targetGen > curGen) {
throw new IllegalArgumentException("targetGen=" + targetGen + " was never returned by this NRTManager instance (current gen=" + curGen + ")");
}
- reopenLock.lockInterruptibly();
+ genLock.lockInterruptibly();
try {
if (targetGen > searchingGen) {
for (WaitingListener listener : waitingListeners) {
@@ -310,7 +308,7 @@ public class NRTManager implements Close
}
}
} finally {
- reopenLock.unlock();
+ genLock.unlock();
}
} catch (InterruptedException ie) {
throw new ThreadInterruptedException(ie);
@@ -319,7 +317,7 @@ public class NRTManager implements Close
private boolean waitOnGenCondition(long time, TimeUnit unit)
throws InterruptedException {
- assert reopenLock.isHeldByCurrentThread();
+ assert genLock.isHeldByCurrentThread();
if (time < 0) {
newGeneration.await();
return true;
@@ -333,51 +331,63 @@ public class NRTManager implements Close
return searchingGen;
}
- public void maybeReopen() throws IOException {
- if (reopenLock.tryLock()) {
- try {
- // Mark gen as of when reopen started:
- final long newSearcherGen = writer.getAndIncrementGeneration();
- if (searchingGen == MAX_SEARCHER_GEN) {
- newGeneration.signalAll(); // wake up threads if we have a new generation
- return;
- }
- boolean setSearchGen;
- if (!mgr.isSearcherCurrent()) {
- setSearchGen = mgr.maybeRefresh();
- } else {
- setSearchGen = true;
- }
- if (setSearchGen) {
- searchingGen = newSearcherGen;// update searcher gen
- newGeneration.signalAll(); // wake up threads if we have a new generation
- }
- } finally {
- reopenLock.unlock();
+ private long lastRefreshGen;
+
+ @Override
+ protected IndexSearcher refreshIfNeeded(IndexSearcher referenceToRefresh) throws IOException {
+ // Record gen as of when reopen started:
+ lastRefreshGen = writer.getAndIncrementGeneration();
+ final IndexReader r = referenceToRefresh.getIndexReader();
+ IndexSearcher newSearcher = null;
+ if (!r.isCurrent()) {
+ final IndexReader newReader = IndexReader.openIfChanged(r);
+ if (newReader != null) {
+ newSearcher = SearcherManager.getSearcher(searcherFactory, newReader);
+ }
+ }
+
+ return newSearcher;
+ }
+
+ @Override
+ protected void afterRefresh() {
+ genLock.lock();
+ try {
+ if (searchingGen != MAX_SEARCHER_GEN) {
+ // update searchingGen:
+ assert lastRefreshGen >= searchingGen;
+ searchingGen = lastRefreshGen;
}
+ // wake up threads if we have a new generation:
+ newGeneration.signalAll();
+ } finally {
+ genLock.unlock();
+ }
+ }
+
+ @Override
+ protected synchronized void afterClose() throws IOException {
+ genLock.lock();
+ try {
+ // max it out to make sure nobody can wait on another gen
+ searchingGen = MAX_SEARCHER_GEN;
+ newGeneration.signalAll();
+ } finally {
+ genLock.unlock();
}
}
/**
- * Close this NRTManager to future searching. Any searches still in process in
- * other threads won't be affected, and they should still call
- * {@link SearcherManager#release} after they are done.
- *
- * <p>
- * <b>NOTE</b>: caller must separately close the writer.
+ * Returns <code>true</code> if no changes have occured since this searcher
+ * ie. reader was opened, otherwise <code>false</code>.
+ * @see IndexReader#isCurrent()
*/
- public void close() throws IOException {
- reopenLock.lock();
+ public boolean isSearcherCurrent() throws IOException {
+ final IndexSearcher searcher = acquire();
try {
- try {
- // max it out to make sure nobody can wait on another gen
- searchingGen = MAX_SEARCHER_GEN;
- mgr.close();
- } finally { // make sure we signal even if close throws an exception
- newGeneration.signalAll();
- }
+ return searcher.getIndexReader().isCurrent();
} finally {
- reopenLock.unlock();
+ release(searcher);
}
}
}
Modified: lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManagerReopenThread.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManagerReopenThread.java?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManagerReopenThread.java (original)
+++ lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/NRTManagerReopenThread.java Fri Feb 17 19:30:06 2012
@@ -181,7 +181,7 @@ public class NRTManagerReopenThread exte
lastReopenStartNS = System.nanoTime();
try {
//final long t0 = System.nanoTime();
- manager.maybeReopen();
+ manager.maybeRefresh();
//System.out.println("reopen took " + ((System.nanoTime()-t0)/1000000.0) + " msec");
} catch (IOException ioe) {
//System.out.println(Thread.currentThread().getName() + ": IOE");
Modified: lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java (original)
+++ lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/ReferenceManager.java Fri Feb 17 19:30:06 2012
@@ -56,7 +56,7 @@ public abstract class ReferenceManager<G
current = newReference;
release(oldReference);
}
-
+
/** Decrement reference counting on the given reference. */
protected abstract void decRef(G reference) throws IOException;
@@ -100,9 +100,14 @@ public abstract class ReferenceManager<G
// closeable javadoc says:
// if this is already closed then invoking this method has no effect.
swapReference(null);
+ afterClose();
}
}
+ /** Called after close(), so subclass can free any resources. */
+ protected void afterClose() throws IOException {
+ }
+
/**
* You must call this, periodically, if you want that {@link #acquire()} will
* return refreshed instances.
@@ -116,13 +121,16 @@ public abstract class ReferenceManager<G
* refresh to complete.
*
* <p>
- * This method returns true if the reference was in fact refreshed, or if the
- * current reference has no pending changes.
+ * If this method returns true it means the calling thread either refreshed
+ * or that there were no changes to refresh. If it returns false it means another
+ * thread is currently refreshing.
*/
public final boolean maybeRefresh() throws IOException {
ensureOpen();
+
// Ensure only 1 thread does reopen at once; other threads just return immediately:
- if (reopenLock.tryAcquire()) {
+ final boolean doTryRefresh = reopenLock.tryAcquire();
+ if (doTryRefresh) {
try {
final G reference = acquire();
try {
@@ -142,15 +150,20 @@ public abstract class ReferenceManager<G
} finally {
release(reference);
}
- return true;
+ afterRefresh();
} finally {
reopenLock.release();
}
- } else {
- return false;
}
+
+ return doTryRefresh;
}
+ /** Called after swapReference has installed a new
+ * instance. */
+ protected void afterRefresh() throws IOException {
+ }
+
/**
* Release the refernce previously obtained via {@link #acquire()}.
* <p>
@@ -160,5 +173,4 @@ public abstract class ReferenceManager<G
assert reference != null;
decRef(reference);
}
-
}
Modified: lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/SearcherManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/SearcherManager.java?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/SearcherManager.java (original)
+++ lucene/dev/branches/branch_3x/lucene/core/src/java/org/apache/lucene/search/SearcherManager.java Fri Feb 17 19:30:06 2012
@@ -79,9 +79,26 @@ public final class SearcherManager exten
searcherFactory = new SearcherFactory();
}
this.searcherFactory = searcherFactory;
- current = searcherFactory.newSearcher(IndexReader.open(writer, applyAllDeletes));
+ current = getSearcher(searcherFactory, IndexReader.open(writer, applyAllDeletes));
}
+ /**
+ * Creates and returns a new SearcherManager from the given {@link Directory}.
+ * @param dir the directory to open the DirectoryReader on.
+ * @param searcherFactory An optional {@link SearcherFactory}. Pass
+ * <code>null</code> if you don't require the searcher to be warmed
+ * before going live or other custom behavior.
+ *
+ * @throws IOException
+ */
+ public SearcherManager(Directory dir, SearcherFactory searcherFactory) throws IOException {
+ if (searcherFactory == null) {
+ searcherFactory = new SearcherFactory();
+ }
+ this.searcherFactory = searcherFactory;
+ current = getSearcher(searcherFactory, IndexReader.open(dir));
+ }
+
@Override
protected void decRef(IndexSearcher reference) throws IOException {
reference.getIndexReader().decRef();
@@ -93,7 +110,7 @@ public final class SearcherManager exten
if (newReader == null) {
return null;
} else {
- return searcherFactory.newSearcher(newReader);
+ return getSearcher(searcherFactory, newReader);
}
}
@@ -102,25 +119,9 @@ public final class SearcherManager exten
return reference.getIndexReader().tryIncRef();
}
- /**
- * Creates and returns a new SearcherManager from the given {@link Directory}.
- * @param dir the directory to open the IndexReader on.
- * @param searcherFactory An optional {@link SearcherFactory}. Pass
- * <code>null</code> if you don't require the searcher to be warmed
- * before going live or other custom behavior.
- *
- * @throws IOException
- */
- public SearcherManager(Directory dir, SearcherFactory searcherFactory) throws IOException {
- if (searcherFactory == null) {
- searcherFactory = new SearcherFactory();
- }
- this.searcherFactory = searcherFactory;
- current = searcherFactory.newSearcher(IndexReader.open(dir));
- }
-
/** @deprecated see {@link #maybeRefresh()}. */
- public final boolean maybeReopen() throws IOException {
+ @Deprecated
+ public boolean maybeReopen() throws IOException {
return maybeRefresh();
}
@@ -137,5 +138,22 @@ public final class SearcherManager exten
release(searcher);
}
}
-
+
+ // NOTE: decRefs incoming reader on throwing an exception
+ static IndexSearcher getSearcher(SearcherFactory searcherFactory, IndexReader reader) throws IOException {
+ boolean success = false;
+ final IndexSearcher searcher;
+ try {
+ searcher = searcherFactory.newSearcher(reader);
+ if (searcher.getIndexReader() != reader) {
+ throw new IllegalStateException("SearcherFactory must wrap exactly the provided reader (got " + searcher.getIndexReader() + " but expected " + reader + ")");
+ }
+ success = true;
+ } finally {
+ if (!success) {
+ reader.decRef();
+ }
+ }
+ return searcher;
+ }
}
Modified: lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestNRTManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestNRTManager.java?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestNRTManager.java (original)
+++ lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestNRTManager.java Fri Feb 17 19:30:06 2012
@@ -32,6 +32,7 @@ import org.apache.lucene.index.CorruptIn
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.ThreadedIndexingAndSearchingTestCase;
import org.apache.lucene.store.Directory;
@@ -55,7 +56,7 @@ public class TestNRTManager extends Thre
System.out.println("TEST: finalSearcher maxGen=" + maxGen);
}
nrtDeletes.waitForGeneration(maxGen);
- return nrtDeletes.getSearcherManager().acquire();
+ return nrtDeletes.acquire();
}
@Override
@@ -82,14 +83,14 @@ public class TestNRTManager extends Thre
System.out.println(Thread.currentThread().getName() + ": nrt: verify " + id);
}
nrtDeletes.waitForGeneration(gen);
- final IndexSearcher s = nrtDeletes.getSearcherManager().acquire();
+ final IndexSearcher s = nrtDeletes.acquire();
if (VERBOSE) {
System.out.println(Thread.currentThread().getName() + ": nrt: got searcher=" + s);
}
try {
assertEquals(docs.size(), s.search(new TermQuery(id), 10).totalHits);
} finally {
- nrtDeletes.getSearcherManager().release(s);
+ nrtDeletes.release(s);
}
}
@@ -105,14 +106,14 @@ public class TestNRTManager extends Thre
System.out.println(Thread.currentThread().getName() + ": nrt: verify " + id);
}
nrtNoDeletes.waitForGeneration(gen);
- final IndexSearcher s = nrtNoDeletes.getSearcherManager().acquire();
+ final IndexSearcher s = nrtNoDeletes.acquire();
if (VERBOSE) {
System.out.println(Thread.currentThread().getName() + ": nrt: got searcher=" + s);
}
try {
assertEquals(docs.size(), s.search(new TermQuery(id), 10).totalHits);
} finally {
- nrtNoDeletes.getSearcherManager().release(s);
+ nrtNoDeletes.release(s);
}
}
lastGens.set(gen);
@@ -128,14 +129,14 @@ public class TestNRTManager extends Thre
System.out.println(Thread.currentThread().getName() + ": nrt: verify " + id);
}
nrtNoDeletes.waitForGeneration(gen);
- final IndexSearcher s = nrtNoDeletes.getSearcherManager().acquire();
+ final IndexSearcher s = nrtNoDeletes.acquire();
if (VERBOSE) {
System.out.println(Thread.currentThread().getName() + ": nrt: got searcher=" + s);
}
try {
assertEquals(1, s.search(new TermQuery(id), 10).totalHits);
} finally {
- nrtNoDeletes.getSearcherManager().release(s);
+ nrtNoDeletes.release(s);
}
}
lastGens.set(gen);
@@ -150,14 +151,14 @@ public class TestNRTManager extends Thre
System.out.println(Thread.currentThread().getName() + ": nrt: verify " + id);
}
nrtDeletes.waitForGeneration(gen);
- final IndexSearcher s = nrtDeletes.getSearcherManager().acquire();
+ final IndexSearcher s = nrtDeletes.acquire();
if (VERBOSE) {
System.out.println(Thread.currentThread().getName() + ": nrt: got searcher=" + s);
}
try {
assertEquals(1, s.search(new TermQuery(id), 10).totalHits);
} finally {
- nrtDeletes.getSearcherManager().release(s);
+ nrtDeletes.release(s);
}
}
lastGens.set(gen);
@@ -172,14 +173,14 @@ public class TestNRTManager extends Thre
System.out.println(Thread.currentThread().getName() + ": nrt: verify del " + id);
}
nrtDeletes.waitForGeneration(gen);
- final IndexSearcher s = nrtDeletes.getSearcherManager().acquire();
+ final IndexSearcher s = nrtDeletes.acquire();
if (VERBOSE) {
System.out.println(Thread.currentThread().getName() + ": nrt: got searcher=" + s);
}
try {
assertEquals(0, s.search(new TermQuery(id), 10).totalHits);
} finally {
- nrtDeletes.getSearcherManager().release(s);
+ nrtDeletes.release(s);
}
}
lastGens.set(gen);
@@ -263,7 +264,7 @@ public class TestNRTManager extends Thre
nrt = nrtNoDeletes;
}
- return nrt.getSearcherManager().acquire();
+ return nrt.acquire();
}
@Override
@@ -272,7 +273,7 @@ public class TestNRTManager extends Thre
// against the same NRT mgr you acquired from... but
// both impls just decRef the underlying reader so we
// can get away w/ cheating:
- nrtNoDeletes.getSearcherManager().release(s);
+ nrtNoDeletes.release(s);
}
@Override
@@ -302,15 +303,15 @@ public class TestNRTManager extends Thre
Document doc = new Document();
doc.add(newField("test","test", Store.YES, Index.ANALYZED));
long gen = writer.addDocument(doc);
- manager.maybeReopen();
+ manager.maybeRefresh();
assertFalse(gen < manager.getCurrentSearchingGen());
Thread t = new Thread() {
public void run() {
try {
signal.await();
- manager.maybeReopen();
+ manager.maybeRefresh();
writer.deleteDocuments(new TermQuery(new Term("foo", "barista")));
- manager.maybeReopen(); // kick off another reopen so we inc. the internal gen
+ manager.maybeRefresh(); // kick off another reopen so we inc. the internal gen
} catch (Exception e) {
e.printStackTrace();
} finally {
@@ -322,13 +323,13 @@ public class TestNRTManager extends Thre
_writer.waitAfterUpdate = true; // wait in addDocument to let some reopens go through
final long lastGen = writer.updateDocument(new Term("foo", "bar"), doc); // once this returns the doc is already reflected in the last reopen
- assertFalse(manager.getSearcherManager().isSearcherCurrent()); // false since there is a delete in the queue
+ assertFalse(manager.isSearcherCurrent()); // false since there is a delete in the queue
- IndexSearcher acquire = manager.getSearcherManager().acquire();
+ IndexSearcher searcher = manager.acquire();
try {
- assertEquals(2, acquire.getIndexReader().numDocs());
+ assertEquals(2, searcher.getIndexReader().numDocs());
} finally {
- manager.getSearcherManager().release(acquire);
+ manager.release(searcher);
}
NRTManagerReopenThread thread = new NRTManagerReopenThread(manager, 0.01, 0.01);
thread.start(); // start reopening
@@ -344,7 +345,7 @@ public class TestNRTManager extends Thre
}
};
waiter.start();
- manager.maybeReopen();
+ manager.maybeRefresh();
waiter.join(1000);
if (!finished.get()) {
waiter.interrupt();
@@ -384,4 +385,28 @@ public class TestNRTManager extends Thre
}
}
}
+
+ public void testEvilSearcherFactory() throws Exception {
+ final Directory dir = newDirectory();
+ final RandomIndexWriter w = new RandomIndexWriter(random, dir);
+ w.commit();
+
+ final IndexReader other = IndexReader.open(dir);
+
+ final SearcherFactory theEvilOne = new SearcherFactory() {
+ @Override
+ public IndexSearcher newSearcher(IndexReader ignored) throws IOException {
+ return new IndexSearcher(other);
+ }
+ };
+
+ try {
+ new NRTManager(new NRTManager.TrackingIndexWriter(w.w), theEvilOne);
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+ w.close();
+ other.close();
+ dir.close();
+ }
}
Modified: lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestSearcherManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestSearcherManager.java?rev=1245720&r1=1245719&r2=1245720&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestSearcherManager.java (original)
+++ lucene/dev/branches/branch_3x/lucene/core/src/test/org/apache/lucene/search/TestSearcherManager.java Fri Feb 17 19:30:06 2012
@@ -32,6 +32,7 @@ import org.apache.lucene.index.Concurren
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.ThreadedIndexingAndSearchingTestCase;
import org.apache.lucene.store.AlreadyClosedException;
@@ -312,5 +313,33 @@ public class TestSearcherManager extends
}
dir.close();
}
-
+
+ public void testEvilSearcherFactory() throws Exception {
+ final Directory dir = newDirectory();
+ final RandomIndexWriter w = new RandomIndexWriter(random, dir);
+ w.commit();
+
+ final IndexReader other = IndexReader.open(dir);
+
+ final SearcherFactory theEvilOne = new SearcherFactory() {
+ @Override
+ public IndexSearcher newSearcher(IndexReader ignored) throws IOException {
+ return new IndexSearcher(other);
+ }
+ };
+
+ try {
+ new SearcherManager(dir, theEvilOne);
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+ try {
+ new SearcherManager(w.w, random.nextBoolean(), theEvilOne);
+ } catch (IllegalStateException ise) {
+ // expected
+ }
+ w.close();
+ other.close();
+ dir.close();
+ }
}