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
|
@ -80,7 +80,7 @@ abstract class DirectoryIndexReader extends IndexReader implements Cloneable {
|
|||
boolean hasSegmentInfos() {
|
||||
return segmentInfos != null;
|
||||
}
|
||||
|
||||
|
||||
protected DirectoryIndexReader() {}
|
||||
|
||||
DirectoryIndexReader(Directory directory, SegmentInfos segmentInfos,
|
||||
|
@ -167,11 +167,16 @@ abstract class DirectoryIndexReader extends IndexReader implements Cloneable {
|
|||
|
||||
public final synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
|
||||
|
||||
final SegmentInfos infos = (SegmentInfos) segmentInfos.clone();
|
||||
DirectoryIndexReader newReader = doReopen(infos, true, openReadOnly);
|
||||
final SegmentInfos clonedInfos;
|
||||
if (segmentInfos != null) {
|
||||
clonedInfos = (SegmentInfos) segmentInfos.clone();
|
||||
} else {
|
||||
clonedInfos = null;
|
||||
}
|
||||
DirectoryIndexReader newReader = doReopen(clonedInfos, true, openReadOnly);
|
||||
|
||||
if (this != newReader) {
|
||||
newReader.init(directory, infos, closeDirectory, openReadOnly);
|
||||
newReader.init(directory, clonedInfos, closeDirectory, openReadOnly);
|
||||
newReader.deletionPolicy = deletionPolicy;
|
||||
}
|
||||
|
||||
|
|
|
@ -1184,13 +1184,21 @@ public abstract class IndexReader implements Cloneable {
|
|||
return DirectoryIndexReader.listCommits(dir);
|
||||
}
|
||||
|
||||
/** Returns the sequential sub readers that this reader is
|
||||
* logically composed of. IndexSearcher uses this API to
|
||||
* drive searching by one sub reader at a time. If this
|
||||
* reader is not composed of sequential child readers, it
|
||||
* should return null. If this method returns an empty
|
||||
* array, that means this reader is a null reader (for
|
||||
* example a MultiReader that has no sub readers).*/
|
||||
/** Expert: returns the sequential sub readers that this
|
||||
* reader is logically composed of. For example,
|
||||
* IndexSearcher uses this API to drive searching by one
|
||||
* sub reader at a time. If this reader is not composed
|
||||
* of sequential child readers, it should return null.
|
||||
* If this method returns an empty array, that means this
|
||||
* 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() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -625,8 +625,15 @@ class SegmentReader extends DirectoryIndexReader {
|
|||
|
||||
protected synchronized DirectoryIndexReader doReopen(SegmentInfos infos, boolean doClone, boolean openReadOnly) throws CorruptIndexException, IOException {
|
||||
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);
|
||||
if (segment.equals(si.name) && si.getUseCompoundFile() == SegmentReader.this.si.getUseCompoundFile()) {
|
||||
newReader = reopenSegment(si, doClone, openReadOnly);
|
||||
|
|
|
@ -403,4 +403,24 @@ public class TestIndexReaderClone extends LuceneTestCase {
|
|||
private void assertDelDocsRefCountEquals(int refCount, SegmentReader reader) {
|
||||
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