LUCENE-3464: rename IR.reopen -> IR.openIfChanged, and return null (not old reader) if there are no changes

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1178612 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2011-10-03 22:07:00 +00:00
parent e0b0721fbc
commit ae43014041
32 changed files with 328 additions and 252 deletions

View File

@ -608,6 +608,11 @@ Changes in backwards compatibility policy
As this is expert API, most code will not be affected.
(Uwe Schindler, Doron Cohen, Mike McCandless)
* LUCENE-3464: IndexReader.reopen has been renamed to
IndexReader.openIfChanged (a static method), and now returns null
(instead of the old reader) if there are no changes in the index, to
prevent the common pitfall of accidentally closing the old reader.
Bug fixes
* LUCENE-3412: SloppyPhraseScorer was returning non-deterministic results

View File

@ -521,4 +521,9 @@ you can now do this:
* LUCENE-3396: Analyzer.tokenStream() and .reusableTokenStream() have been made final.
It is now necessary to use Analyzer.TokenStreamComponents to define an analysis process.
Analyzer also has its own way of managing the reuse of TokenStreamComponents (either
globally, or per-field). To define another Strategy, implement Analyzer.ReuseStrategy.
globally, or per-field). To define another Strategy, implement Analyzer.ReuseStrategy.
* LUCENE-3464: IndexReader.reopen has been renamed to
IndexReader.openIfChanged (a static method), and now returns null
(instead of the old reader) if there are no changes to the index, to
prevent the common pitfall of accidentally closing the old reader.

View File

@ -307,7 +307,14 @@ public class NRTManager implements Closeable {
// Start from whichever searcher is most current:
final IndexSearcher startSearcher = noDeletesSearchingGen.get() > searchingGen.get() ? noDeletesCurrentSearcher : currentSearcher;
final IndexReader nextReader = startSearcher.getIndexReader().reopen(writer, applyDeletes);
IndexReader nextReader = IndexReader.openIfChanged(startSearcher.getIndexReader(), writer, applyDeletes);
if (nextReader == null) {
// NOTE: doesn't happen currently in Lucene (reopen on
// NRT reader always returns new reader), but could in
// the future:
nextReader = startSearcher.getIndexReader();
nextReader.incRef();
}
if (nextReader != startSearcher.getIndexReader()) {
final IndexSearcher nextSearcher = new IndexSearcher(nextReader, es);

View File

@ -111,7 +111,7 @@ public class SearcherManager implements Closeable {
}
/** You must call this, periodically, to perform a
* reopen. This calls {@link IndexReader#reopen} on the
* reopen. This calls {@link IndexReader#openIfChanged} on the
* underlying reader, and if that returns a new reader,
* it's warmed (if you provided a {@link SearcherWarmer}
* and then swapped into production.
@ -139,8 +139,8 @@ public class SearcherManager implements Closeable {
// threads just return immediately:
if (reopening.tryAcquire()) {
try {
IndexReader newReader = currentSearcher.getIndexReader().reopen();
if (newReader != currentSearcher.getIndexReader()) {
IndexReader newReader = IndexReader.openIfChanged(currentSearcher.getIndexReader());
if (newReader != null) {
IndexSearcher newSearcher = new IndexSearcher(newReader, es);
boolean success = false;
try {

View File

@ -45,9 +45,6 @@ public class TestMultiPassIndexSplitter extends LuceneTestCase {
input = IndexReader.open(dir, false);
// delete the last doc
input.deleteDocument(input.maxDoc() - 1);
IndexReader inputOld = input;
input = input.reopen(true);
inputOld.close();
}
@Override

View File

@ -65,8 +65,8 @@ public class TestNRTCachingDirectory extends LuceneTestCase {
if (r == null) {
r = IndexReader.open(w.w, false);
} else {
final IndexReader r2 = r.reopen();
if (r2 != r) {
final IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != null) {
r.close();
r = r2;
}

View File

@ -198,8 +198,8 @@ class DirectoryReader extends IndexReader implements Cloneable {
initialize(readers.toArray(new SegmentReader[readers.size()]));
}
/** This constructor is only used for {@link #reopen()} */
DirectoryReader(Directory directory, SegmentInfos infos, SegmentReader[] oldReaders, int[] oldStarts,
/** This constructor is only used for {@link #doOpenIfChanged()} */
DirectoryReader(Directory directory, SegmentInfos infos, SegmentReader[] oldReaders,
boolean readOnly, boolean doClone, int termInfosIndexDivisor, CodecProvider codecs,
Collection<ReaderFinishedListener> readerFinishedListeners) throws IOException {
this.directory = directory;
@ -255,18 +255,21 @@ class DirectoryReader extends IndexReader implements Cloneable {
// this is a new reader; in case we hit an exception we can close it safely
newReader = SegmentReader.get(readOnly, infos.info(i), termInfosIndexDivisor, IOContext.READ);
newReader.readerFinishedListeners = readerFinishedListeners;
} else {
newReader = newReaders[i].reopenSegment(infos.info(i), doClone, readOnly);
assert newReader.readerFinishedListeners == readerFinishedListeners;
}
if (newReader == newReaders[i]) {
// this reader will be shared between the old and the new one,
// so we must incRef it
readerShared[i] = true;
newReader.incRef();
} else {
readerShared[i] = false;
newReaders[i] = newReader;
} else {
newReader = newReaders[i].reopenSegment(infos.info(i), doClone, readOnly);
if (newReader == null) {
// this reader will be shared between the old and the new one,
// so we must incRef it
readerShared[i] = true;
newReaders[i].incRef();
} else {
assert newReader.readerFinishedListeners == readerFinishedListeners;
readerShared[i] = false;
// Steal ref returned to us by reopenSegment:
newReaders[i] = newReader;
}
}
success = true;
} finally {
@ -364,8 +367,8 @@ class DirectoryReader extends IndexReader implements Cloneable {
@Override
public final synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
// doReopen calls ensureOpen
DirectoryReader newReader = doReopen((SegmentInfos) segmentInfos.clone(), true, openReadOnly);
// doOpenIfChanged calls ensureOpen
DirectoryReader newReader = doOpenIfChanged((SegmentInfos) segmentInfos.clone(), true, openReadOnly);
if (this != newReader) {
newReader.deletionPolicy = deletionPolicy;
@ -388,22 +391,24 @@ class DirectoryReader extends IndexReader implements Cloneable {
}
@Override
public final IndexReader reopen() throws CorruptIndexException, IOException {
protected final IndexReader doOpenIfChanged() throws CorruptIndexException, IOException {
// Preserve current readOnly
return doReopen(readOnly, null);
return doOpenIfChanged(readOnly, null);
}
@Override
public final IndexReader reopen(boolean openReadOnly) throws CorruptIndexException, IOException {
return doReopen(openReadOnly, null);
protected final IndexReader doOpenIfChanged(boolean openReadOnly) throws CorruptIndexException, IOException {
return doOpenIfChanged(openReadOnly, null);
}
@Override
public final IndexReader reopen(final IndexCommit commit) throws CorruptIndexException, IOException {
return doReopen(true, commit);
protected final IndexReader doOpenIfChanged(final IndexCommit commit) throws CorruptIndexException, IOException {
return doOpenIfChanged(true, commit);
}
private final IndexReader doReopenFromWriter(boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
// NOTE: always returns a non-null result (ie new reader)
// but that could change someday
private final IndexReader doOpenFromWriter(boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
assert readOnly;
if (!openReadOnly) {
@ -422,7 +427,7 @@ class DirectoryReader extends IndexReader implements Cloneable {
return reader;
}
private IndexReader doReopen(final boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
private IndexReader doOpenIfChanged(final boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
ensureOpen();
assert commit == null || openReadOnly;
@ -430,13 +435,13 @@ class DirectoryReader extends IndexReader implements Cloneable {
// If we were obtained by writer.getReader(), re-ask the
// writer to get a new reader.
if (writer != null) {
return doReopenFromWriter(openReadOnly, commit);
return doOpenFromWriter(openReadOnly, commit);
} else {
return doReopenNoWriter(openReadOnly, commit);
return doOpenNoWriter(openReadOnly, commit);
}
}
private synchronized IndexReader doReopenNoWriter(final boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
private synchronized IndexReader doOpenNoWriter(final boolean openReadOnly, IndexCommit commit) throws CorruptIndexException, IOException {
if (commit == null) {
if (hasChanges) {
@ -451,25 +456,26 @@ class DirectoryReader extends IndexReader implements Cloneable {
if (openReadOnly) {
return clone(openReadOnly);
} else {
return this;
return null;
}
} else if (isCurrent()) {
if (openReadOnly != readOnly) {
// Just fallback to clone
return clone(openReadOnly);
} else {
return this;
return null;
}
}
} else {
if (directory != commit.getDirectory())
if (directory != commit.getDirectory()) {
throw new IOException("the specified commit does not match the specified Directory");
}
if (segmentInfos != null && commit.getSegmentsFileName().equals(segmentInfos.getCurrentSegmentFileName())) {
if (readOnly != openReadOnly) {
// Just fallback to clone
return clone(openReadOnly);
} else {
return this;
return null;
}
}
}
@ -479,15 +485,13 @@ class DirectoryReader extends IndexReader implements Cloneable {
protected Object doBody(String segmentFileName) throws CorruptIndexException, IOException {
final SegmentInfos infos = new SegmentInfos(codecs);
infos.read(directory, segmentFileName, codecs);
return doReopen(infos, false, openReadOnly);
return doOpenIfChanged(infos, false, openReadOnly);
}
}.run(commit);
}
private synchronized DirectoryReader doReopen(SegmentInfos infos, boolean doClone, boolean openReadOnly) throws CorruptIndexException, IOException {
DirectoryReader reader;
reader = new DirectoryReader(directory, infos, subReaders, starts, openReadOnly, doClone, termInfosIndexDivisor, codecs, readerFinishedListeners);
return reader;
private synchronized DirectoryReader doOpenIfChanged(SegmentInfos infos, boolean doClone, boolean openReadOnly) throws CorruptIndexException, IOException {
return new DirectoryReader(directory, infos, subReaders, openReadOnly, doClone, termInfosIndexDivisor, codecs, readerFinishedListeners);
}
/** Version number when this IndexReader was opened. */

View File

@ -344,7 +344,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
* @throws CorruptIndexException
* @throws IOException if there is a low-level IO error
*
* @see #reopen(IndexWriter,boolean)
* @see #openIfChanged(IndexReader,IndexWriter,boolean)
*
* @lucene.experimental
*/
@ -537,90 +537,81 @@ public abstract class IndexReader implements Cloneable,Closeable {
}
/**
* Refreshes an IndexReader if the index has changed since this instance
* was (re)opened.
* <p>
* 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.
* <p>
* 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 <b>not</b> closed and remains usable.<br>
* <p>
* 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.
* <p>
* You can determine whether a reader was actually reopened by comparing the
* old instance with the instance returned by this method:
* <pre>
* IndexReader reader = ...
* ...
* IndexReader newReader = r.reopen();
* if (newReader != reader) {
* ... // reader was reopened
* reader.close();
* }
* reader = newReader;
* ...
* </pre>
* 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.
* <p>This method is typically far less costly than opening a
* fully new <code>IndexReader</code> as it shares
* resources (for example sub-readers) with the provided
* <code>IndexReader</code>, when possible.
*
* <p><b>NOTE</b>: 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.
* <p>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
* <code>SearcherManager</code> in
* <code>contrib/misc</code> to simplify managing this.
*
* <p>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.
*
* <p><b>NOTE</b>: 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 <code>readOnly</code>; 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
* <code>readOnly=true</code> 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).
*
* <p>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}.
*
* <p>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}.</p>
*
* <p>You must close the {@link IndexReader} returned by
* this method once you are done using it.</p>
*
* <p>It's <i>near</i> 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.</p>
*
* <p>The resulting reader supports {@link
* IndexReader#reopen}, but that call will simply forward
* back to this method (though this may change in the
* future).</p>
*
* <p>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 {
* <p>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</p>.
* over, so far.</p>
*
* <p><b>NOTE</b>: 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}.</p>
*
* @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.
* <p>
* 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.
*
* <p>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 {
*
* <p>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.
*
* <p>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).</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @throws CorruptIndexException if the index is corrupt

View File

@ -99,14 +99,14 @@ public class MultiReader extends IndexReader implements Cloneable {
/**
* Tries to reopen the subreaders.
* <br>
* If one or more subreaders could be re-opened (i. e. subReader.reopen()
* returned a new instance != subReader), then a new MultiReader instance
* If one or more subreaders could be re-opened (i. e. IndexReader.openIfChanged(subReader)
* returned a new instance), then a new MultiReader instance
* is returned, otherwise this instance is returned.
* <p>
* 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}).
* <p>
* 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;
}
}

View File

@ -229,12 +229,12 @@ public class ParallelReader extends IndexReader {
* <br>
* 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.
* <p>
* 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}).
* <p>
* 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;
}
}

View File

@ -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

View File

@ -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)}).

View File

@ -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();

View File

@ -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);

View File

@ -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<IndexCommit> commits = IndexReader.listCommits(dir);
for (final IndexCommit commit : commits) {
IndexReader r2 = r.reopen(commit);
IndexReader r2 = IndexReader.openIfChanged(r, commit);
assertNotNull(r2);
assertTrue(r2 != r);
// Reader should be readOnly
@ -1262,7 +1285,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
assertEquals(17, ints[0]);
// Reopen to readonly w/ no chnages
IndexReader r3 = r.reopen(true);
IndexReader r3 = IndexReader.openIfChanged(r, true);
assertNotNull(r3);
assertTrue(((DirectoryReader) r3).readOnly);
r3.close();
@ -1271,7 +1295,8 @@ public class TestIndexReaderReopen extends LuceneTestCase {
writer.commit();
// Reopen reader1 --> reader2
IndexReader r2 = r.reopen(true);
IndexReader r2 = IndexReader.openIfChanged(r, true);
assertNotNull(r2);
r.close();
assertTrue(((DirectoryReader) r2).readOnly);
IndexReader[] subs = r2.getSequentialSubReaders();

View File

@ -1402,7 +1402,8 @@ public class TestIndexWriter extends LuceneTestCase {
if (iter == 1) {
w.commit();
}
IndexReader r2 = r.reopen();
IndexReader r2 = IndexReader.openIfChanged(r);
assertNotNull(r2);
assertTrue(r != r2);
files = Arrays.asList(dir.listAll());

View File

@ -348,7 +348,8 @@ public class TestIndexWriterCommit extends LuceneTestCase {
f.setValue(s);
w.addDocument(doc);
w.commit();
IndexReader r2 = r.reopen();
IndexReader r2 = IndexReader.openIfChanged(r);
assertNotNull(r2);
assertTrue(r2 != r);
r.close();
r = r2;
@ -390,7 +391,8 @@ public class TestIndexWriterCommit extends LuceneTestCase {
IndexReader reader = IndexReader.open(dir, true);
assertEquals(0, reader.numDocs());
writer.commit();
IndexReader reader2 = reader.reopen();
IndexReader reader2 = IndexReader.openIfChanged(reader);
assertNotNull(reader2);
assertEquals(0, reader.numDocs());
assertEquals(23, reader2.numDocs());
reader.close();
@ -530,7 +532,8 @@ public class TestIndexWriterCommit extends LuceneTestCase {
writer.commit();
IndexReader reader3 = reader.reopen();
IndexReader reader3 = IndexReader.openIfChanged(reader);
assertNotNull(reader3);
assertEquals(0, reader.numDocs());
assertEquals(0, reader2.numDocs());
assertEquals(23, reader3.numDocs());
@ -586,10 +589,10 @@ public class TestIndexWriterCommit extends LuceneTestCase {
writer.rollback();
IndexReader reader3 = reader.reopen();
IndexReader reader3 = IndexReader.openIfChanged(reader);
assertNull(reader3);
assertEquals(0, reader.numDocs());
assertEquals(0, reader2.numDocs());
assertEquals(0, reader3.numDocs());
reader.close();
reader2.close();
@ -597,8 +600,6 @@ public class TestIndexWriterCommit extends LuceneTestCase {
for (int i = 0; i < 17; i++)
TestIndexWriter.addDoc(writer);
assertEquals(0, reader3.numDocs());
reader3.close();
reader = IndexReader.open(dir, true);
assertEquals(0, reader.numDocs());
reader.close();

View File

@ -677,8 +677,8 @@ public class TestIndexWriterReader extends LuceneTestCase {
}
((ConcurrentMergeScheduler) writer.getConfig().getMergeScheduler()).sync();
IndexReader r2 = r1.reopen();
if (r2 != r1) {
IndexReader r2 = IndexReader.openIfChanged(r1);
if (r2 != null) {
r1.close();
r1 = r2;
}
@ -709,7 +709,7 @@ public class TestIndexWriterReader extends LuceneTestCase {
assertEquals(100, searcher.search(q, 10).totalHits);
searcher.close();
try {
r.reopen();
IndexReader.openIfChanged(r);
fail("failed to hit AlreadyClosedException");
} catch (AlreadyClosedException ace) {
// expected
@ -766,8 +766,8 @@ public class TestIndexWriterReader extends LuceneTestCase {
int lastCount = 0;
while(System.currentTimeMillis() < endTime) {
IndexReader r2 = r.reopen();
if (r2 != r) {
IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != null) {
r.close();
r = r2;
}
@ -783,7 +783,7 @@ public class TestIndexWriterReader extends LuceneTestCase {
threads[i].join();
}
// final check
IndexReader r2 = r.reopen();
IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != r) {
r.close();
r = r2;
@ -856,7 +856,7 @@ public class TestIndexWriterReader extends LuceneTestCase {
int sum = 0;
while(System.currentTimeMillis() < endTime) {
IndexReader r2 = r.reopen();
IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != r) {
r.close();
r = r2;
@ -871,8 +871,8 @@ public class TestIndexWriterReader extends LuceneTestCase {
threads[i].join();
}
// at least search once
IndexReader r2 = r.reopen();
if (r2 != r) {
IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != null) {
r.close();
r = r2;
}

View File

@ -41,8 +41,8 @@ public class TestNRTThreads extends ThreadedIndexingAndSearchingTestCase {
if (VERBOSE) {
System.out.println("TEST: now reopen r=" + r);
}
final IndexReader r2 = r.reopen();
if (r != r2) {
final IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != null) {
r.close();
r = r2;
}

View File

@ -92,8 +92,8 @@ public class TestNeverDelete extends LuceneTestCase {
for(String fileName : allFiles) {
assertTrue("file " + fileName + " does not exist", d.fileExists(fileName));
}
IndexReader r2 = r.reopen();
if (r2 != r) {
IndexReader r2 = IndexReader.openIfChanged(r);
if (r2 != null) {
r.close();
r = r2;
}

View File

@ -135,8 +135,8 @@ public class TestRollingUpdates extends LuceneTestCase {
if (open == null) {
open = IndexReader.open(writer, true);
}
IndexReader reader = open.reopen();
if (reader != open) {
IndexReader reader = IndexReader.openIfChanged(open);
if (reader != null) {
open.close();
open = reader;
}

View File

@ -147,7 +147,7 @@ public class TestStressNRT extends LuceneTestCase {
if (VERBOSE) {
System.out.println("TEST: " + Thread.currentThread().getName() + ": reopen reader=" + oldReader + " version=" + version);
}
newReader = oldReader.reopen(writer.w, true);
newReader = IndexReader.openIfChanged(oldReader, writer.w, true);
}
} else {
// assertU(commit());
@ -158,13 +158,14 @@ public class TestStressNRT extends LuceneTestCase {
if (VERBOSE) {
System.out.println("TEST: " + Thread.currentThread().getName() + ": now reopen after commit");
}
newReader = oldReader.reopen();
newReader = IndexReader.openIfChanged(oldReader);
}
// Code below assumes newReader comes w/
// extra ref:
if (newReader == oldReader) {
newReader.incRef();
if (newReader == null) {
oldReader.incRef();
newReader = oldReader;
}
oldReader.decRef();

View File

@ -152,10 +152,12 @@ public class TestCachingSpanFilter extends LuceneTestCase {
private static IndexReader refreshReader(IndexReader reader) throws IOException {
IndexReader oldReader = reader;
reader = reader.reopen();
if (reader != oldReader) {
reader = IndexReader.openIfChanged(reader);
if (reader != null) {
oldReader.close();
return reader;
} else {
return oldReader;
}
return reader;
}
}

View File

@ -304,10 +304,12 @@ public class TestCachingWrapperFilter extends LuceneTestCase {
private static IndexReader refreshReader(IndexReader reader) throws IOException {
IndexReader oldReader = reader;
reader = reader.reopen();
if (reader != oldReader) {
reader = IndexReader.openIfChanged(reader);
if (reader != null) {
oldReader.close();
return reader;
} else {
return oldReader;
}
return reader;
}
}

View File

@ -77,8 +77,8 @@ public class NearRealtimeReaderTask extends PerfTask {
}
t = System.currentTimeMillis();
final IndexReader newReader = r.reopen();
if (r != newReader) {
final IndexReader newReader = IndexReader.openIfChanged(r);
if (newReader != null) {
final int delay = (int) (System.currentTimeMillis()-t);
if (reopenTimes.length == reopenCount) {
reopenTimes = ArrayUtil.grow(reopenTimes, 1+reopenCount);

View File

@ -34,8 +34,8 @@ public class ReopenReaderTask extends PerfTask {
@Override
public int doLogic() throws IOException {
IndexReader r = getRunData().getIndexReader();
IndexReader nr = r.reopen();
if (nr != r) {
IndexReader nr = IndexReader.openIfChanged(r);
if (nr != null) {
getRunData().setIndexReader(nr);
nr.decRef();
}

View File

@ -368,8 +368,8 @@ public class LuceneTaxonomyReader implements TaxonomyReader {
// safely read indexReader without holding the write lock, because
// no other thread can be writing at this time (this method is the
// only possible writer, and it is "synchronized" to avoid this case).
IndexReader r2 = indexReader.reopen();
if (indexReader != r2) {
IndexReader r2 = IndexReader.openIfChanged(indexReader);
if (r2 != null) {
IndexReader oldreader = indexReader;
// we can close the old searcher, but need to synchronize this
// so that we don't close it in the middle that another routine

View File

@ -564,8 +564,8 @@ public class LuceneTaxonomyWriter implements TaxonomyWriter {
private synchronized void refreshReader() throws IOException {
if (reader != null) {
IndexReader r2 = reader.reopen();
if (reader != r2) {
IndexReader r2 = IndexReader.openIfChanged(reader);
if (r2 != null) {
reader.close();
reader = r2;
}

View File

@ -299,7 +299,8 @@ public class TestTotalFacetCountsCache extends LuceneTestCase {
writers[0].taxWriter.close();
readers[0].taxReader.refresh();
IndexReader r2 = readers[0].indexReader.reopen();
IndexReader r2 = IndexReader.openIfChanged(readers[0].indexReader);
assertNotNull(r2);
// Hold on to the 'original' reader so we can do some checks with it
IndexReader origReader = null;

View File

@ -160,10 +160,10 @@ public class TestIndexClose extends LuceneTestCase {
// System.err.println("opened "+mynum);
}
@Override
public synchronized IndexReader reopen() throws CorruptIndexException, IOException {
IndexReader n = in.reopen();
if (n==in) {
return this;
protected synchronized IndexReader doOpenIfChanged() throws CorruptIndexException, IOException {
IndexReader n = IndexReader.openIfChanged(in);
if (n == null) {
return null;
}
return new InstrumentedIndexReader(n);
}

View File

@ -1115,10 +1115,11 @@ public final class SolrCore implements SolrInfoMBean {
IndexReader currentReader = newestSearcher.get().getIndexReader();
IndexReader newReader;
newReader = currentReader.reopen();
newReader = IndexReader.openIfChanged(currentReader);
if (newReader == currentReader) {
if (newReader == null) {
currentReader.incRef();
newReader = currentReader;
}
tmp = new SolrIndexSearcher(this, schema, "main", newReader, true, true, true, directoryFactory);

View File

@ -385,11 +385,12 @@ public class DirectUpdateHandler2 extends UpdateHandler {
IndexReader currentReader = previousSearcher.getIndexReader();
IndexReader newReader;
newReader = currentReader.reopen(indexWriterProvider.getIndexWriter(core), true);
newReader = IndexReader.openIfChanged(currentReader, indexWriterProvider.getIndexWriter(core), true);
if (newReader == currentReader) {
if (newReader == null) {
currentReader.incRef();
newReader = currentReader;
}
return new SolrIndexSearcher(core, schema, "main", newReader, true, true, true, core.getDirectoryFactory());