mirror of https://github.com/apache/lucene.git
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:
parent
e0b0721fbc
commit
ae43014041
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}).
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue