diff --git a/src/java/org/apache/lucene/index/MultiReader.java b/src/java/org/apache/lucene/index/MultiReader.java index 13aac0bb10b..8253f440993 100644 --- a/src/java/org/apache/lucene/index/MultiReader.java +++ b/src/java/org/apache/lucene/index/MultiReader.java @@ -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 */ diff --git a/src/java/org/apache/lucene/index/MultiSegmentReader.java b/src/java/org/apache/lucene/index/MultiSegmentReader.java index b326e84caa9..a1a47c447be 100644 --- a/src/java/org/apache/lucene/index/MultiSegmentReader.java +++ b/src/java/org/apache/lucene/index/MultiSegmentReader.java @@ -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 { diff --git a/src/test/org/apache/lucene/index/TestMultiSegmentReader.java b/src/test/org/apache/lucene/index/TestMultiSegmentReader.java index 848ebc970bc..2e0913e229f 100644 --- a/src/test/org/apache/lucene/index/TestMultiSegmentReader.java +++ b/src/test/org/apache/lucene/index/TestMultiSegmentReader.java @@ -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;