mirror of https://github.com/apache/lucene.git
LUCENE-1314: allow clone of subreaders; add note to getSequentialSubReaders javadoc to not use sub-readers to make changes
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@744653 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8b79fa51a5
commit
cd89bc9de3
|
@ -167,11 +167,16 @@ abstract class DirectoryIndexReader extends IndexReader implements Cloneable {
|
||||||
|
|
||||||
public final synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
|
public final synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
|
||||||
|
|
||||||
final SegmentInfos infos = (SegmentInfos) segmentInfos.clone();
|
final SegmentInfos clonedInfos;
|
||||||
DirectoryIndexReader newReader = doReopen(infos, true, openReadOnly);
|
if (segmentInfos != null) {
|
||||||
|
clonedInfos = (SegmentInfos) segmentInfos.clone();
|
||||||
|
} else {
|
||||||
|
clonedInfos = null;
|
||||||
|
}
|
||||||
|
DirectoryIndexReader newReader = doReopen(clonedInfos, true, openReadOnly);
|
||||||
|
|
||||||
if (this != newReader) {
|
if (this != newReader) {
|
||||||
newReader.init(directory, infos, closeDirectory, openReadOnly);
|
newReader.init(directory, clonedInfos, closeDirectory, openReadOnly);
|
||||||
newReader.deletionPolicy = deletionPolicy;
|
newReader.deletionPolicy = deletionPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1184,13 +1184,21 @@ public abstract class IndexReader implements Cloneable {
|
||||||
return DirectoryIndexReader.listCommits(dir);
|
return DirectoryIndexReader.listCommits(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the sequential sub readers that this reader is
|
/** Expert: returns the sequential sub readers that this
|
||||||
* logically composed of. IndexSearcher uses this API to
|
* reader is logically composed of. For example,
|
||||||
* drive searching by one sub reader at a time. If this
|
* IndexSearcher uses this API to drive searching by one
|
||||||
* reader is not composed of sequential child readers, it
|
* sub reader at a time. If this reader is not composed
|
||||||
* should return null. If this method returns an empty
|
* of sequential child readers, it should return null.
|
||||||
* array, that means this reader is a null reader (for
|
* If this method returns an empty array, that means this
|
||||||
* example a MultiReader that has no sub readers).*/
|
* reader is a null reader (for example a MultiReader
|
||||||
|
* that has no sub readers).
|
||||||
|
* <p>
|
||||||
|
* NOTE: for a MultiSegmentReader, which is obtained by
|
||||||
|
* {@link #open} when the index has more than one
|
||||||
|
* segment, you should not use the sub-readers returned
|
||||||
|
* by this method to make any changes (setNorm,
|
||||||
|
* deleteDocument, etc.). Doing so will likely lead to
|
||||||
|
* index corruption. Use the parent reader instead. */
|
||||||
public IndexReader[] getSequentialSubReaders() {
|
public IndexReader[] getSequentialSubReaders() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -626,7 +626,14 @@ class SegmentReader extends DirectoryIndexReader {
|
||||||
protected synchronized DirectoryIndexReader doReopen(SegmentInfos infos, boolean doClone, boolean openReadOnly) throws CorruptIndexException, IOException {
|
protected synchronized DirectoryIndexReader doReopen(SegmentInfos infos, boolean doClone, boolean openReadOnly) throws CorruptIndexException, IOException {
|
||||||
DirectoryIndexReader newReader;
|
DirectoryIndexReader newReader;
|
||||||
|
|
||||||
if (infos.size() == 1) {
|
if (infos == null) {
|
||||||
|
if (doClone) {
|
||||||
|
// OK: directly clone myself
|
||||||
|
newReader = reopenSegment(si, doClone, openReadOnly);
|
||||||
|
} else {
|
||||||
|
throw new UnsupportedOperationException("cannot reopen a standalone SegmentReader");
|
||||||
|
}
|
||||||
|
} else if (infos.size() == 1) {
|
||||||
SegmentInfo si = infos.info(0);
|
SegmentInfo si = infos.info(0);
|
||||||
if (segment.equals(si.name) && si.getUseCompoundFile() == SegmentReader.this.si.getUseCompoundFile()) {
|
if (segment.equals(si.name) && si.getUseCompoundFile() == SegmentReader.this.si.getUseCompoundFile()) {
|
||||||
newReader = reopenSegment(si, doClone, openReadOnly);
|
newReader = reopenSegment(si, doClone, openReadOnly);
|
||||||
|
|
|
@ -403,4 +403,24 @@ public class TestIndexReaderClone extends LuceneTestCase {
|
||||||
private void assertDelDocsRefCountEquals(int refCount, SegmentReader reader) {
|
private void assertDelDocsRefCountEquals(int refCount, SegmentReader reader) {
|
||||||
assertEquals(refCount, reader.deletedDocsRef.refCount());
|
assertEquals(refCount, reader.deletedDocsRef.refCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCloneSubreaders() throws Exception {
|
||||||
|
final Directory dir1 = new MockRAMDirectory();
|
||||||
|
|
||||||
|
TestIndexReaderReopen.createIndex(dir1, true);
|
||||||
|
IndexReader reader = IndexReader.open(dir1);
|
||||||
|
reader.deleteDocument(1); // acquire write lock
|
||||||
|
IndexReader[] subs = reader.getSequentialSubReaders();
|
||||||
|
assert subs.length > 1;
|
||||||
|
|
||||||
|
IndexReader[] clones = new IndexReader[subs.length];
|
||||||
|
for (int x=0; x < subs.length; x++) {
|
||||||
|
clones[x] = (IndexReader) subs[x].clone();
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
for (int x=0; x < subs.length; x++) {
|
||||||
|
clones[x].close();
|
||||||
|
}
|
||||||
|
dir1.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue