LUCENE-1596: check that enum and termdocs came from same reader before invoking optimization

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@775201 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2009-05-15 15:50:12 +00:00
parent f4415a3924
commit ca5a7436fa
3 changed files with 49 additions and 13 deletions

View File

@ -329,12 +329,12 @@ public class MultiReader extends IndexReader implements Cloneable {
public TermEnum terms() throws IOException {
ensureOpen();
return new MultiTermEnum(subReaders, starts, null);
return new MultiTermEnum(this, subReaders, starts, null);
}
public TermEnum terms(Term term) throws IOException {
ensureOpen();
return new MultiTermEnum(subReaders, starts, term);
return new MultiTermEnum(this, subReaders, starts, term);
}
public int docFreq(Term t) throws IOException {
@ -347,12 +347,12 @@ public class MultiReader extends IndexReader implements Cloneable {
public TermDocs termDocs() throws IOException {
ensureOpen();
return new MultiTermDocs(subReaders, starts);
return new MultiTermDocs(this, subReaders, starts);
}
public TermPositions termPositions() throws IOException {
ensureOpen();
return new MultiTermPositions(subReaders, starts);
return new MultiTermPositions(this, subReaders, starts);
}
/** @deprecated */

View File

@ -437,12 +437,12 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
public TermEnum terms() throws IOException {
ensureOpen();
return new MultiTermEnum(subReaders, starts, null);
return new MultiTermEnum(this, subReaders, starts, null);
}
public TermEnum terms(Term term) throws IOException {
ensureOpen();
return new MultiTermEnum(subReaders, starts, term);
return new MultiTermEnum(this, subReaders, starts, term);
}
public int docFreq(Term t) throws IOException {
@ -455,12 +455,12 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
public TermDocs termDocs() throws IOException {
ensureOpen();
return new MultiTermDocs(subReaders, starts);
return new MultiTermDocs(this, subReaders, starts);
}
public TermPositions termPositions() throws IOException {
ensureOpen();
return new MultiTermPositions(subReaders, starts);
return new MultiTermPositions(this, subReaders, starts);
}
protected void commitChanges() throws IOException {
@ -529,14 +529,16 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
}
static class MultiTermEnum extends TermEnum {
IndexReader topReader; // used for matching TermEnum to TermDocs
private SegmentMergeQueue queue;
private Term term;
private int docFreq;
final SegmentMergeInfo[] matchingSegments; // null terminated array of matching segments
public MultiTermEnum(IndexReader[] readers, int[] starts, Term t)
public MultiTermEnum(IndexReader topReader, IndexReader[] readers, int[] starts, Term t)
throws IOException {
this.topReader = topReader;
queue = new SegmentMergeQueue(readers.length);
matchingSegments = new SegmentMergeInfo[readers.length+1];
for (int i = 0; i < readers.length; i++) {
@ -609,6 +611,7 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
}
static class MultiTermDocs implements TermDocs {
IndexReader topReader; // used for matching TermEnum to TermDocs
protected IndexReader[] readers;
protected int[] starts;
protected Term term;
@ -623,7 +626,8 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
int matchingSegmentPos; // position into the matching segments from tenum
SegmentMergeInfo smi; // current segment mere info... can be null
public MultiTermDocs(IndexReader[] r, int[] s) {
public MultiTermDocs(IndexReader topReader, IndexReader[] r, int[] s) {
this.topReader = topReader;
readers = r;
starts = s;
@ -650,7 +654,9 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
public void seek(TermEnum termEnum) throws IOException {
seek(termEnum.term());
if (termEnum instanceof MultiTermEnum) {
this.tenum = (MultiTermEnum)termEnum;
tenum = (MultiTermEnum)termEnum;
if (topReader != tenum.topReader)
tenum = null;
}
}
@ -756,8 +762,8 @@ class MultiSegmentReader extends DirectoryIndexReader implements Cloneable {
}
static class MultiTermPositions extends MultiTermDocs implements TermPositions {
public MultiTermPositions(IndexReader[] r, int[] s) {
super(r,s);
public MultiTermPositions(IndexReader topReader, IndexReader[] r, int[] s) {
super(topReader,r,s);
}
protected TermDocs termDocs(IndexReader reader) throws IOException {

View File

@ -149,6 +149,36 @@ public class TestMultiSegmentReader extends LuceneTestCase {
mr.close();
}
public void testMultiTermDocs() throws IOException {
RAMDirectory ramDir1=new RAMDirectory();
addDoc(ramDir1, "test foo", true);
RAMDirectory ramDir2=new RAMDirectory();
addDoc(ramDir2, "test blah", true);
RAMDirectory ramDir3=new RAMDirectory();
addDoc(ramDir3, "test wow", true);
IndexReader[] readers1 = new IndexReader[]{IndexReader.open(ramDir1), IndexReader.open(ramDir3)};
IndexReader[] readers2 = new IndexReader[]{IndexReader.open(ramDir1), IndexReader.open(ramDir2), IndexReader.open(ramDir3)};
MultiReader mr2 = new MultiReader(readers1);
MultiReader mr3 = new MultiReader(readers2);
// test mixing up TermDocs and TermEnums from different readers.
TermDocs td2 = mr2.termDocs();
TermEnum te3 = mr3.terms(new Term("body","wow"));
td2.seek(te3);
int ret = 0;
// This should blow up if we forget to check that the TermEnum is from the same
// reader as the TermDocs.
while (td2.next()) ret += td2.doc();
td2.close();
te3.close();
// really a dummy assert to ensure that we got some docs and to ensure that
// nothing is optimized out.
assertTrue(ret > 0);
}
public void testAllTermDocs() throws IOException {
IndexReader reader = openReader();
int NUM_DOCS = 2;