LUCENE-2534: fix over-sharing bug in MultiTerms/Docs/AndPositionsEnum

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@963538 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2010-07-13 00:12:17 +00:00
parent 7dc191922c
commit fa7d244cee
5 changed files with 41 additions and 12 deletions

View File

@ -411,6 +411,10 @@ Bug fixes
primary & secondary dirs share the same underlying directory.
(Michael McCandless)
* LUCENE-2534: fix over-sharing bug in
MultiTermsEnum.docs/AndPositionsEnum. (Robert Muir, Mike
McCandless)
New features
* LUCENE-2128: Parallelized fetching document frequencies during weight

View File

@ -40,7 +40,12 @@ public final class MultiDocsAndPositionsEnum extends DocsAndPositionsEnum {
MultiDocsAndPositionsEnum reset(final EnumWithSlice[] subs, final int numSubs) throws IOException {
this.numSubs = numSubs;
this.subs = subs;
this.subs = new EnumWithSlice[subs.length];
for(int i=0;i<subs.length;i++) {
this.subs[i] = new EnumWithSlice();
this.subs[i].docsAndPositionsEnum = subs[i].docsAndPositionsEnum;
this.subs[i].slice = subs[i].slice;
}
upto = -1;
current = null;
return this;

View File

@ -38,7 +38,13 @@ public final class MultiDocsEnum extends DocsEnum {
MultiDocsEnum reset(final EnumWithSlice[] subs, final int numSubs) throws IOException {
this.numSubs = numSubs;
this.subs = subs;
this.subs = new EnumWithSlice[subs.length];
for(int i=0;i<subs.length;i++) {
this.subs[i] = new EnumWithSlice();
this.subs[i].docsEnum = subs[i].docsEnum;
this.subs[i].slice = subs[i].slice;
}
upto = -1;
current = null;
return this;

View File

@ -272,9 +272,9 @@ public final class MultiTermsEnum extends TermsEnum {
b = null;
}
final DocsEnum subDocsEnum = entry.terms.docs(b, entry.reuseDocs);
final DocsEnum subDocsEnum = entry.terms.docs(b, null);
if (subDocsEnum != null) {
entry.reuseDocs = subDocs[upto].docsEnum = subDocsEnum;
subDocs[upto].docsEnum = subDocsEnum;
subDocs[upto].slice = entry.subSlice;
upto++;
@ -334,14 +334,14 @@ public final class MultiTermsEnum extends TermsEnum {
b = null;
}
final DocsAndPositionsEnum subPostings = entry.terms.docsAndPositions(b, entry.reusePostings);
final DocsAndPositionsEnum subPostings = entry.terms.docsAndPositions(b, null);
if (subPostings != null) {
entry.reusePostings = subDocsAndPositions[upto].docsAndPositionsEnum = subPostings;
subDocsAndPositions[upto].docsAndPositionsEnum = subPostings;
subDocsAndPositions[upto].slice = entry.subSlice;
upto++;
} else {
if (entry.terms.docs(b, entry.reuseDocs) != null) {
if (entry.terms.docs(b, null) != null) {
// At least one of our subs does not store
// positions -- we can't correctly produce a
// MultiDocsAndPositions enum
@ -360,8 +360,6 @@ public final class MultiTermsEnum extends TermsEnum {
private final static class TermsEnumWithSlice {
private final ReaderUtil.Slice subSlice;
private TermsEnum terms;
private DocsEnum reuseDocs;
private DocsAndPositionsEnum reusePostings;
public BytesRef current;
public TermsEnumWithSlice(ReaderUtil.Slice subSlice) {
@ -372,9 +370,6 @@ public final class MultiTermsEnum extends TermsEnum {
public void reset(TermsEnum terms, BytesRef term) {
this.terms = terms;
current = term;
// TODO: can we not null these?
reuseDocs = null;
reusePostings = null;
}
}

View File

@ -115,4 +115,23 @@ public class TestMultiFields extends LuceneTestCase {
}
assertEquals(docs.NO_MORE_DOCS, docs.nextDoc());
}
public void testSeparateEnums() throws Exception {
Directory dir = new MockRAMDirectory();
IndexWriter w = new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()));
Document d = new Document();
d.add(new Field("f", "j", Field.Store.NO, Field.Index.NOT_ANALYZED));
w.addDocument(d);
w.commit();
w.addDocument(d);
IndexReader r = w.getReader();
w.close();
DocsEnum d1 = MultiFields.getTermDocsEnum(r, null, "f", new BytesRef("j"));
DocsEnum d2 = MultiFields.getTermDocsEnum(r, null, "f", new BytesRef("j"));
assertEquals(0, d1.nextDoc());
assertEquals(0, d2.nextDoc());
r.close();
dir.close();
}
}