From ae430140414c6c461049658a3dbdcbdaaace4056 Mon Sep 17 00:00:00 2001
From: Michael McCandless
- * Opening an IndexReader is an expensive operation. This method can be used
- * to refresh an existing IndexReader to reduce these costs. This method
- * tries to only load segments that have changed or were created after the
- * IndexReader was (re)opened.
- *
- * If the index has not changed since this instance was (re)opened, then this
- * call is a NOOP and returns this instance. Otherwise, a new instance is
- * returned. The old instance is not closed and remains usable.
- * If the reader is reopened, even though they share
- * resources internally, it's safe to make changes
- * (deletions, norms) with the new reader. All shared
- * mutable state obeys "copy on write" semantics to ensure
- * the changes are not seen by other readers.
- *
- * You can determine whether a reader was actually reopened by comparing the
- * old instance with the instance returned by this method:
- * This method is typically far less costly than opening a
+ * fully new NOTE: If this reader is a near real-time
- * reader (obtained from {@link IndexWriter#getReader()},
- * reopen() will simply call writer.getReader() again for
- * you, though this may change in the future.
+ * The provided reader is not closed (you are responsible
+ * for doing so); if a new reader is returned you also
+ * must eventually close it. Be sure to never close a
+ * reader while other threads are still using it; see
+ * If a new reader is returned, it's safe to make changes
+ * (deletions, norms) with it. All shared mutable state
+ * with the old reader uses "copy on write" semantics to
+ * ensure the changes are not seen by other readers.
+ *
+ * NOTE: If the provided reader is a near real-time
+ * reader, this method will return another near-real-time
+ * reader.
*
* @throws CorruptIndexException if the index is corrupt
* @throws IOException if there is a low-level IO error
+ * @return null if there are no changes; else, a new
+ * IndexReader instance which you must eventually close
*/
- public synchronized IndexReader reopen() throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support reopen().");
- }
-
-
- /** Just like {@link #reopen()}, except you can change the
- * readOnly of the original reader. If the index is
- * unchanged but readOnly is different then a new reader
- * will be returned. */
- public synchronized IndexReader reopen(boolean openReadOnly) throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support reopen().");
- }
-
- /** Expert: reopen this reader on a specific commit point.
- * This always returns a readOnly reader. If the
- * specified commit point matches what this reader is
- * already on, and this reader is already readOnly, then
- * this same instance is returned; if it is not already
- * readOnly, a readOnly clone is returned. */
- public synchronized IndexReader reopen(final IndexCommit commit) throws CorruptIndexException, IOException {
- throw new UnsupportedOperationException("This reader does not support reopen(IndexCommit).");
+ public static IndexReader openIfChanged(IndexReader oldReader) throws IOException {
+ return oldReader.doOpenIfChanged();
}
/**
- * Expert: returns a readonly reader, covering all
- * committed as well as un-committed changes to the index.
- * This provides "near real-time" searching, in that
- * changes made during an IndexWriter session can be
+ * If the index has changed since the provided reader was
+ * opened, open and return a new reader, with the
+ * specified This provides "near real-time" searching, in that
+ * changes made during an {@link IndexWriter} session can be
* quickly made available for searching without closing
* the writer nor calling {@link #commit}.
*
- * Note that this is functionally equivalent to calling
- * {#flush} (an internal IndexWriter operation) and then using {@link IndexReader#open} to
- * open a new reader. But the turnaround time of this
- * method should be faster since it avoids the potentially
- * costly {@link #commit}. You must close the {@link IndexReader} returned by
- * this method once you are done using it. It's near real-time because there is no hard
* guarantee on how quickly you can get a new reader after
* making changes with IndexWriter. You'll have to
@@ -629,11 +620,6 @@ public abstract class IndexReader implements Cloneable,Closeable {
* feature, please report back on your findings so we can
* learn, improve and iterate. The resulting reader supports {@link
- * IndexReader#reopen}, but that call will simply forward
- * back to this method (though this may change in the
- * future). The very first time this method is called, this
* writer instance will make every effort to pool the
* readers that it opens for doing merges, applying
@@ -649,7 +635,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
* If an addIndexes* call is running in another thread,
* then this reader will only search those segments from
* the foreign index that have been successfully copied
- * over, so far
- *
- * IndexReader reader = ...
- * ...
- * IndexReader newReader = r.reopen();
- * if (newReader != reader) {
- * ... // reader was reopened
- * reader.close();
- * }
- * reader = newReader;
- * ...
- *
+ * If the index has changed since the provided reader was
+ * opened, open and return a new reader; else, return
+ * null. The new reader, if not null, will be the same
+ * type of reader as the previous one, ie an NRT reader
+ * will open a new NRT reader, a MultiReader will open a
+ * new MultiReader, etc.
*
- * Be sure to synchronize that code so that other threads,
- * if present, can never use reader after it has been
- * closed and before it's switched to newReader.
+ * IndexReader
as it shares
+ * resources (for example sub-readers) with the provided
+ * IndexReader
, when possible.
*
- * SearcherManager
in
+ * contrib/misc
to simplify managing this.
+ *
+ * readOnly
; else, return
+ * null.
+ *
+ * @see #openIfChanged(IndexReader)
+ */
+ public static IndexReader openIfChanged(IndexReader oldReader, boolean readOnly) throws IOException {
+ return oldReader.doOpenIfChanged(readOnly);
+ }
+
+ /**
+ * If the IndexCommit differs from what the
+ * provided reader is searching, or the provided reader is
+ * not already read-only, open and return a new
+ * readOnly=true
reader; else, return null.
+ *
+ * @see #openIfChanged(IndexReader)
+ */
+ // TODO: should you be able to specify readOnly?
+ public static IndexReader openIfChanged(IndexReader oldReader, IndexCommit commit) throws IOException {
+ return oldReader.doOpenIfChanged(commit);
+ }
+
+ /**
+ * Expert: If there changes (committed or not) in the
+ * {@link IndexWriter} versus what the provided reader is
+ * searching, then open and return a new read-only
+ * IndexReader searching both committed and uncommitted
+ * changes from the writer; else, return null (though, the
+ * current implementation never returns null).
+ *
+ *
NOTE: Once the writer is closed, any * outstanding readers may continue to be used. However, @@ -657,9 +643,11 @@ public abstract class IndexReader implements Cloneable,Closeable { * hit an {@link AlreadyClosedException}.
* * @return IndexReader that covers entire index plus all - * changes made so far by this IndexWriter instance + * changes made so far by this IndexWriter instance, or + * null if there are no new changes * * @param writer The IndexWriter to open from + * * @param applyAllDeletes If true, all buffered deletes will * be applied (made visible) in the returned reader. If * false, the deletes are not applied but remain buffered @@ -672,7 +660,23 @@ public abstract class IndexReader implements Cloneable,Closeable { * * @lucene.experimental */ - public IndexReader reopen(IndexWriter writer, boolean applyAllDeletes) throws CorruptIndexException, IOException { + public static IndexReader openIfChanged(IndexReader oldReader, IndexWriter writer, boolean applyAllDeletes) throws IOException { + return oldReader.doOpenIfChanged(writer, applyAllDeletes); + } + + protected IndexReader doOpenIfChanged() throws CorruptIndexException, IOException { + throw new UnsupportedOperationException("This reader does not support reopen()."); + } + + protected IndexReader doOpenIfChanged(boolean openReadOnly) throws CorruptIndexException, IOException { + throw new UnsupportedOperationException("This reader does not support reopen()."); + } + + protected IndexReader doOpenIfChanged(final IndexCommit commit) throws CorruptIndexException, IOException { + throw new UnsupportedOperationException("This reader does not support reopen(IndexCommit)."); + } + + protected IndexReader doOpenIfChanged(IndexWriter writer, boolean applyAllDeletes) throws CorruptIndexException, IOException { return writer.getReader(applyAllDeletes); } @@ -687,7 +691,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * changes to the index on close, but the old reader still * reflects all changes made up until it was cloned. *- * Like {@link #reopen()}, it's safe to make changes to + * Like {@link #openIfChanged(IndexReader)}, it's safe to make changes to * either the original or the cloned reader: all shared * mutable state obeys "copy on write" semantics to ensure * the changes are not seen by other readers. @@ -808,7 +812,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * implemented in the IndexReader base class. * *
If this reader is based on a Directory (ie, was - * created by calling {@link #open}, or {@link #reopen} on + * created by calling {@link #open}, or {@link #openIfChanged} on * a reader based on a Directory), then this method * returns the version recorded in the commit that the * reader opened. This version is advanced every time @@ -816,7 +820,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * *
If instead this reader is a near real-time reader * (ie, obtained by a call to {@link - * IndexWriter#getReader}, or by calling {@link #reopen} + * IndexWriter#getReader}, or by calling {@link #openIfChanged} * on a near real-time reader), then this method returns * the version of the last commit done by the writer. * Note that even as further changes are made with the @@ -849,14 +853,14 @@ public abstract class IndexReader implements Cloneable,Closeable { * index since this reader was opened. * *
If this reader is based on a Directory (ie, was - * created by calling {@link #open}, or {@link #reopen} on + * created by calling {@link #open}, or {@link #openIfChanged} on * a reader based on a Directory), then this method checks * if any further commits (see {@link IndexWriter#commit} * have occurred in that directory).
* *If instead this reader is a near real-time reader * (ie, obtained by a call to {@link - * IndexWriter#getReader}, or by calling {@link #reopen} + * IndexWriter#getReader}, or by calling {@link #openIfChanged} * on a near real-time reader), then this method checks if * either a new commmit has occurred, or any new * uncommitted changes have taken place via the writer. @@ -864,7 +868,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * merging, this method will still return false.
* *In any event, if this returns false, you should call - * {@link #reopen} to get a new reader that sees the + * {@link #openIfChanged} to get a new reader that sees the * changes.
* * @throws CorruptIndexException if the index is corrupt diff --git a/lucene/src/java/org/apache/lucene/index/MultiReader.java b/lucene/src/java/org/apache/lucene/index/MultiReader.java index dfdc0dbb052..1cef8208051 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiReader.java +++ b/lucene/src/java/org/apache/lucene/index/MultiReader.java @@ -99,14 +99,14 @@ public class MultiReader extends IndexReader implements Cloneable { /** * Tries to reopen the subreaders. ** A re-opened instance might share one or more subreaders with the old * instance. Index modification operations result in undefined behavior * when performed before the old instance is closed. - * (see {@link IndexReader#reopen()}). + * (see {@link IndexReader#openIfChanged}). *
* If subreaders are shared, then the reference count of those
* readers is increased to ensure that the subreaders remain open
@@ -116,8 +116,8 @@ public class MultiReader extends IndexReader implements Cloneable {
* @throws IOException if there is a low-level IO error
*/
@Override
- public synchronized IndexReader reopen() throws CorruptIndexException, IOException {
- return doReopen(false);
+ protected synchronized IndexReader doOpenIfChanged() throws CorruptIndexException, IOException {
+ return doOpenIfChanged(false);
}
/**
@@ -132,7 +132,7 @@ public class MultiReader extends IndexReader implements Cloneable {
@Override
public synchronized Object clone() {
try {
- return doReopen(true);
+ return doOpenIfChanged(true);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@@ -146,33 +146,35 @@ public class MultiReader extends IndexReader implements Cloneable {
/**
* If clone is true then we clone each of the subreaders
* @param doClone
- * @return New IndexReader, or same one (this) if
- * reopen/clone is not necessary
+ * @return New IndexReader, or null if open/clone is not necessary
* @throws CorruptIndexException
* @throws IOException
*/
- protected IndexReader doReopen(boolean doClone) throws CorruptIndexException, IOException {
+ protected IndexReader doOpenIfChanged(boolean doClone) throws CorruptIndexException, IOException {
ensureOpen();
- boolean reopened = false;
+ boolean changed = false;
IndexReader[] newSubReaders = new IndexReader[subReaders.length];
boolean success = false;
try {
for (int i = 0; i < subReaders.length; i++) {
- if (doClone)
+ if (doClone) {
newSubReaders[i] = (IndexReader) subReaders[i].clone();
- else
- newSubReaders[i] = subReaders[i].reopen();
- // if at least one of the subreaders was updated we remember that
- // and return a new MultiReader
- if (newSubReaders[i] != subReaders[i]) {
- reopened = true;
+ changed = true;
+ } else {
+ final IndexReader newSubReader = IndexReader.openIfChanged(subReaders[i]);
+ if (newSubReader != null) {
+ newSubReaders[i] = newSubReader;
+ changed = true;
+ } else {
+ newSubReaders[i] = subReaders[i];
+ }
}
}
success = true;
} finally {
- if (!success && reopened) {
+ if (!success && changed) {
for (int i = 0; i < newSubReaders.length; i++) {
if (newSubReaders[i] != subReaders[i]) {
try {
@@ -185,7 +187,7 @@ public class MultiReader extends IndexReader implements Cloneable {
}
}
- if (reopened) {
+ if (changed) {
boolean[] newDecrefOnClose = new boolean[subReaders.length];
for (int i = 0; i < subReaders.length; i++) {
if (newSubReaders[i] == subReaders[i]) {
@@ -197,7 +199,7 @@ public class MultiReader extends IndexReader implements Cloneable {
mr.decrefOnClose = newDecrefOnClose;
return mr;
} else {
- return this;
+ return null;
}
}
diff --git a/lucene/src/java/org/apache/lucene/index/ParallelReader.java b/lucene/src/java/org/apache/lucene/index/ParallelReader.java
index df4b731cd3f..04ce475dfd1 100644
--- a/lucene/src/java/org/apache/lucene/index/ParallelReader.java
+++ b/lucene/src/java/org/apache/lucene/index/ParallelReader.java
@@ -229,12 +229,12 @@ public class ParallelReader extends IndexReader {
*
* If one or more subreaders could be re-opened (i. e. subReader.reopen()
* returned a new instance != subReader), then a new ParallelReader instance
- * is returned, otherwise this instance is returned.
+ * is returned, otherwise null is returned.
*
* A re-opened instance might share one or more subreaders with the old * instance. Index modification operations result in undefined behavior * when performed before the old instance is closed. - * (see {@link IndexReader#reopen()}). + * (see {@link IndexReader#openIfChanged}). *
* If subreaders are shared, then the reference count of those
* readers is increased to ensure that the subreaders remain open
@@ -244,7 +244,7 @@ public class ParallelReader extends IndexReader {
* @throws IOException if there is a low-level IO error
*/
@Override
- public synchronized IndexReader reopen() throws CorruptIndexException, IOException {
+ protected synchronized IndexReader doOpenIfChanged() throws CorruptIndexException, IOException {
// doReopen calls ensureOpen
return doReopen(false);
}
@@ -262,15 +262,16 @@ public class ParallelReader extends IndexReader {
IndexReader newReader = null;
if (doClone) {
newReader = (IndexReader) oldReader.clone();
+ reopened = true;
} else {
- newReader = oldReader.reopen();
+ newReader = IndexReader.openIfChanged(oldReader);
+ if (newReader != null) {
+ reopened = true;
+ } else {
+ newReader = oldReader;
+ }
}
newReaders.add(newReader);
- // if at least one of the subreaders was updated we remember that
- // and return a new ParallelReader
- if (newReader != oldReader) {
- reopened = true;
- }
}
success = true;
} finally {
@@ -310,7 +311,7 @@ public class ParallelReader extends IndexReader {
return pr;
} else {
// No subreader was refreshed
- return this;
+ return null;
}
}
diff --git a/lucene/src/java/org/apache/lucene/index/SegmentReader.java b/lucene/src/java/org/apache/lucene/index/SegmentReader.java
index 10f1cf91445..92462bb6ed6 100644
--- a/lucene/src/java/org/apache/lucene/index/SegmentReader.java
+++ b/lucene/src/java/org/apache/lucene/index/SegmentReader.java
@@ -204,13 +204,13 @@ public class SegmentReader extends IndexReader implements Cloneable {
}
@Override
- public synchronized IndexReader reopen()
+ protected synchronized IndexReader doOpenIfChanged()
throws CorruptIndexException, IOException {
return reopenSegment(si, false, readOnly);
}
@Override
- public synchronized IndexReader reopen(boolean openReadOnly)
+ protected synchronized IndexReader doOpenIfChanged(boolean openReadOnly)
throws CorruptIndexException, IOException {
return reopenSegment(si, false, openReadOnly);
}
@@ -233,7 +233,7 @@ public class SegmentReader extends IndexReader implements Cloneable {
// if we're cloning we need to run through the reopenSegment logic
// also if both old and new readers aren't readonly, we clone to avoid sharing modifications
if (normsUpToDate && deletionsUpToDate && !doClone && openReadOnly && readOnly) {
- return this;
+ return null;
}
// When cloning, the incoming SegmentInfos should not
diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java
index 6e1d49440e9..b70f3021440 100644
--- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -54,7 +54,7 @@ import org.apache.lucene.util.ThreadInterruptedException;
* multiple searches instead of creating a new one
* per-search. If your index has changed and you wish to
* see the changes reflected in searching, you should
- * use {@link IndexReader#reopen} to obtain a new reader and
+ * use {@link IndexReader#openIfChanged} to obtain a new reader and
* then create a new IndexSearcher from that. Also, for
* low-latency turnaround it's best to use a near-real-time
* reader ({@link IndexReader#open(IndexWriter,boolean)}).
diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java
index a55bfe33fa2..ec6c8c6ad51 100644
--- a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java
+++ b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java
@@ -92,7 +92,8 @@ public class TestIndexReader extends LuceneTestCase
addDocumentWithFields(writer);
writer.close();
- IndexReader r3 = r2.reopen();
+ IndexReader r3 = IndexReader.openIfChanged(r2);
+ assertNotNull(r3);
assertFalse(c.equals(r3.getIndexCommit()));
assertFalse(r2.getIndexCommit().isOptimized());
r3.close();
@@ -103,7 +104,8 @@ public class TestIndexReader extends LuceneTestCase
writer.optimize();
writer.close();
- r3 = r2.reopen();
+ r3 = IndexReader.openIfChanged(r2);
+ assertNotNull(r3);
assertTrue(r3.getIndexCommit().isOptimized());
r2.close();
r3.close();
@@ -965,7 +967,8 @@ public class TestIndexReader extends LuceneTestCase
addDocumentWithFields(writer);
writer.close();
- IndexReader r2 = r.reopen();
+ IndexReader r2 = IndexReader.openIfChanged(r);
+ assertNotNull(r2);
assertFalse(c.equals(r2.getIndexCommit()));
assertFalse(r2.getIndexCommit().isOptimized());
r2.close();
@@ -976,7 +979,9 @@ public class TestIndexReader extends LuceneTestCase
writer.optimize();
writer.close();
- r2 = r.reopen();
+ r2 = IndexReader.openIfChanged(r);
+ assertNotNull(r2);
+ assertNull(IndexReader.openIfChanged(r2));
assertTrue(r2.getIndexCommit().isOptimized());
r.close();
@@ -1011,7 +1016,8 @@ public class TestIndexReader extends LuceneTestCase
writer.close();
// Make sure reopen is still readonly:
- IndexReader r2 = r.reopen();
+ IndexReader r2 = IndexReader.openIfChanged(r);
+ assertNotNull(r2);
r.close();
assertFalse(r == r2);
@@ -1030,7 +1036,8 @@ public class TestIndexReader extends LuceneTestCase
writer.close();
// Make sure reopen to a single segment is still readonly:
- IndexReader r3 = r2.reopen();
+ IndexReader r3 = IndexReader.openIfChanged(r2);
+ assertNotNull(r3);
assertFalse(r3 == r2);
r2.close();
@@ -1179,7 +1186,8 @@ public class TestIndexReader extends LuceneTestCase
writer.commit();
// Reopen reader1 --> reader2
- IndexReader r2 = r.reopen();
+ IndexReader r2 = IndexReader.openIfChanged(r);
+ assertNotNull(r2);
r.close();
IndexReader sub0 = r2.getSequentialSubReaders()[0];
final int[] ints2 = FieldCache.DEFAULT.getInts(sub0, "number");
@@ -1206,7 +1214,8 @@ public class TestIndexReader extends LuceneTestCase
assertEquals(36, r1.getUniqueTermCount());
writer.addDocument(doc);
writer.commit();
- IndexReader r2 = r.reopen();
+ IndexReader r2 = IndexReader.openIfChanged(r);
+ assertNotNull(r2);
r.close();
try {
r2.getUniqueTermCount();
@@ -1253,7 +1262,9 @@ public class TestIndexReader extends LuceneTestCase
writer.close();
// LUCENE-1718: ensure re-open carries over no terms index:
- IndexReader r2 = r.reopen();
+ IndexReader r2 = IndexReader.openIfChanged(r);
+ assertNotNull(r2);
+ assertNull(IndexReader.openIfChanged(r2));
r.close();
IndexReader[] subReaders = r2.getSequentialSubReaders();
assertEquals(2, subReaders.length);
@@ -1282,8 +1293,8 @@ public class TestIndexReader extends LuceneTestCase
writer.addDocument(doc);
writer.prepareCommit();
assertTrue(r.isCurrent());
- IndexReader r2 = r.reopen();
- assertTrue(r == r2);
+ IndexReader r2 = IndexReader.openIfChanged(r);
+ assertNull(r2);
writer.commit();
assertFalse(r.isCurrent());
writer.close();
diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java b/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java
index 570ee843fbb..4bcfd26500a 100644
--- a/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java
+++ b/lucene/src/test/org/apache/lucene/index/TestIndexReaderClone.java
@@ -115,7 +115,8 @@ public class TestIndexReaderClone extends LuceneTestCase {
TestIndexReaderReopen.modifyIndex(5, dir1);
- IndexReader reader2 = reader1.reopen();
+ IndexReader reader2 = IndexReader.openIfChanged(reader1);
+ assertNotNull(reader2);
assertTrue(reader1 != reader2);
assertTrue(deleteWorked(1, reader2));
@@ -156,7 +157,8 @@ public class TestIndexReaderClone extends LuceneTestCase {
assertTrue(deleteWorked(1, reader));
assertEquals(docCount-1, reader.numDocs());
- IndexReader readOnlyReader = reader.reopen(true);
+ IndexReader readOnlyReader = IndexReader.openIfChanged(reader, true);
+ assertNotNull(readOnlyReader);
if (!isReadOnly(readOnlyReader)) {
fail("reader isn't read only");
}
@@ -394,7 +396,10 @@ public class TestIndexReaderClone extends LuceneTestCase {
assertDelDocsRefCountEquals(1, clonedSegmentReader);
// test a reopened reader
- IndexReader reopenedReader = clonedReader.reopen();
+ IndexReader reopenedReader = IndexReader.openIfChanged(clonedReader);
+ if (reopenedReader == null) {
+ reopenedReader = clonedReader;
+ }
IndexReader cloneReader2 = (IndexReader) reopenedReader.clone();
SegmentReader cloneSegmentReader2 = getOnlySegmentReader(cloneReader2);
assertDelDocsRefCountEquals(2, cloneSegmentReader2);
diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReaderReopen.java b/lucene/src/test/org/apache/lucene/index/TestIndexReaderReopen.java
index 011f9b7162c..30605580f3c 100644
--- a/lucene/src/test/org/apache/lucene/index/TestIndexReaderReopen.java
+++ b/lucene/src/test/org/apache/lucene/index/TestIndexReaderReopen.java
@@ -192,8 +192,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
iwriter.commit();
if (withReopen) {
// reopen
- IndexReader r2 = reader.reopen();
- if (reader != r2) {
+ IndexReader r2 = IndexReader.openIfChanged(reader);
+ if (r2 != null) {
reader.close();
reader = r2;
}
@@ -468,12 +468,15 @@ public class TestIndexReaderReopen extends LuceneTestCase {
modifyIndex(0, dir2);
assertRefCountEquals(1 + mode, reader1);
- IndexReader multiReader2 = multiReader1.reopen();
+ IndexReader multiReader2 = IndexReader.openIfChanged(multiReader1);
+ assertNotNull(multiReader2);
// index1 hasn't changed, so multiReader2 should share reader1 now with multiReader1
assertRefCountEquals(2 + mode, reader1);
modifyIndex(0, dir1);
- IndexReader reader2 = reader1.reopen();
+ IndexReader reader2 = IndexReader.openIfChanged(reader1);
+ assertNotNull(reader2);
+ assertNull(IndexReader.openIfChanged(reader2));
assertRefCountEquals(2 + mode, reader1);
if (mode == 1) {
@@ -481,7 +484,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
}
modifyIndex(1, dir1);
- IndexReader reader3 = reader2.reopen();
+ IndexReader reader3 = IndexReader.openIfChanged(reader2);
+ assertNotNull(reader3);
assertRefCountEquals(2 + mode, reader1);
assertRefCountEquals(1, reader2);
@@ -541,13 +545,16 @@ public class TestIndexReaderReopen extends LuceneTestCase {
modifyIndex(1, dir2);
assertRefCountEquals(1 + mode, reader1);
- IndexReader parallelReader2 = parallelReader1.reopen();
+ IndexReader parallelReader2 = IndexReader.openIfChanged(parallelReader1);
+ assertNotNull(parallelReader2);
+ assertNull(IndexReader.openIfChanged(parallelReader2));
// index1 hasn't changed, so parallelReader2 should share reader1 now with multiReader1
assertRefCountEquals(2 + mode, reader1);
modifyIndex(0, dir1);
modifyIndex(0, dir2);
- IndexReader reader2 = reader1.reopen();
+ IndexReader reader2 = IndexReader.openIfChanged(reader1);
+ assertNotNull(reader2);
assertRefCountEquals(2 + mode, reader1);
if (mode == 1) {
@@ -555,7 +562,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
}
modifyIndex(4, dir1);
- IndexReader reader3 = reader2.reopen();
+ IndexReader reader3 = IndexReader.openIfChanged(reader2);
+ assertNotNull(reader3);
assertRefCountEquals(2 + mode, reader1);
assertRefCountEquals(1, reader2);
@@ -609,25 +617,29 @@ public class TestIndexReaderReopen extends LuceneTestCase {
modifier.deleteDocument(0);
modifier.close();
- IndexReader reader2 = reader1.reopen();
+ IndexReader reader2 = IndexReader.openIfChanged(reader1);
+ assertNotNull(reader2);
modifier = IndexReader.open(dir1, false);
DefaultSimilarity sim = new DefaultSimilarity();
modifier.setNorm(1, "field1", sim.encodeNormValue(50f));
modifier.setNorm(1, "field2", sim.encodeNormValue(50f));
modifier.close();
- IndexReader reader3 = reader2.reopen();
+ IndexReader reader3 = IndexReader.openIfChanged(reader2);
+ assertNotNull(reader3);
SegmentReader segmentReader3 = getOnlySegmentReader(reader3);
modifier = IndexReader.open(dir1, false);
modifier.deleteDocument(2);
modifier.close();
- IndexReader reader4 = reader3.reopen();
+ IndexReader reader4 = IndexReader.openIfChanged(reader3);
+ assertNotNull(reader4);
modifier = IndexReader.open(dir1, false);
modifier.deleteDocument(3);
modifier.close();
- IndexReader reader5 = reader3.reopen();
+ IndexReader reader5 = IndexReader.openIfChanged(reader3);
+ assertNotNull(reader5);
// Now reader2-reader5 references reader1. reader1 and reader2
// share the same norms. reader3, reader4, reader5 also share norms.
@@ -738,11 +750,11 @@ public class TestIndexReaderReopen extends LuceneTestCase {
for (int i = 0; i < n; i++) {
if (i % 2 == 0) {
- IndexReader refreshed = reader.reopen();
- if (refreshed != reader) {
+ IndexReader refreshed = IndexReader.openIfChanged(reader);
+ if (refreshed != null) {
readersToClose.add(reader);
+ reader = refreshed;
}
- reader = refreshed;
}
final IndexReader r = reader;
@@ -766,7 +778,10 @@ public class TestIndexReaderReopen extends LuceneTestCase {
break;
} else {
// not synchronized
- IndexReader refreshed = r.reopen();
+ IndexReader refreshed = IndexReader.openIfChanged(r);
+ if (refreshed == null) {
+ refreshed = r;
+ }
IndexSearcher searcher = newSearcher(refreshed);
ScoreDoc[] hits = searcher.search(
@@ -907,7 +922,10 @@ public class TestIndexReaderReopen extends LuceneTestCase {
IndexReader refreshed = null;
try {
- refreshed = reader.reopen();
+ refreshed = IndexReader.openIfChanged(reader);
+ if (refreshed == null) {
+ refreshed = reader;
+ }
} finally {
if (refreshed == null && r != null) {
// Hit exception -- close opened reader
@@ -1094,7 +1112,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
r2.deleteDocument(0);
r2.close();
- IndexReader r3 = r1.reopen();
+ IndexReader r3 = IndexReader.openIfChanged(r1);
+ assertNotNull(r3);
assertTrue(r1 != r3);
r1.close();
try {
@@ -1118,7 +1137,9 @@ public class TestIndexReaderReopen extends LuceneTestCase {
modifyIndex(5, dir); // Add another doc (3 segments)
- IndexReader r2 = r1.reopen(); // MSR
+ IndexReader r2 = IndexReader.openIfChanged(r1); // MSR
+ assertNotNull(r2);
+ assertNull(IndexReader.openIfChanged(r2));
assertTrue(r1 != r2);
SegmentReader sr1 = (SegmentReader) r1.getSequentialSubReaders()[0]; // Get SRs for the first segment from original
@@ -1151,7 +1172,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
// Add doc:
modifyIndex(5, dir);
- IndexReader r2 = r1.reopen();
+ IndexReader r2 = IndexReader.openIfChanged(r1);
+ assertNotNull(r2);
assertTrue(r1 != r2);
IndexReader[] rs2 = r2.getSequentialSubReaders();
@@ -1207,7 +1229,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
Collection