LUCENE-6246: add simple test for postings reuse/flags/behavior (DOCS_ONLY so far), fix asserting to support reuse

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1660405 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2015-02-17 15:15:00 +00:00
parent 69300ee467
commit 0c483c6cd5
2 changed files with 135 additions and 10 deletions

View File

@ -0,0 +1,97 @@
package org.apache.lucene.index;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LuceneTestCase;
/**
* Test basic postingsenum behavior, flags, reuse, etc.
*/
public class TestPostingsEnum extends LuceneTestCase {
public void testDocsOnly() throws Exception {
Directory dir = newDirectory();
IndexWriterConfig iwc = new IndexWriterConfig(null);
IndexWriter iw = new IndexWriter(dir, iwc);
Document doc = new Document();
doc.add(new StringField("foo", "bar", Field.Store.NO));
iw.addDocument(doc);
DirectoryReader reader = DirectoryReader.open(iw, false);
// sugar method (FREQS)
PostingsEnum postings = getOnlySegmentReader(reader).postings(new Term("foo", "bar"));
assertEquals(-1, postings.docID());
assertEquals(0, postings.nextDoc());
assertEquals(1, postings.freq());
assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
// termsenum reuse (FREQS)
TermsEnum termsEnum = getOnlySegmentReader(reader).terms("foo").iterator(null);
termsEnum.seekExact(new BytesRef("bar"));
PostingsEnum postings2 = termsEnum.postings(null, postings);
assertNotNull(postings2);
assertSame(postings, postings2);
// and it had better work
assertEquals(-1, postings.docID());
assertEquals(0, postings.nextDoc());
assertEquals(1, postings.freq());
assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
// asking for docs only: ok
PostingsEnum docsOnly = termsEnum.postings(null, null, PostingsEnum.NONE);
assertEquals(-1, docsOnly.docID());
assertEquals(0, docsOnly.nextDoc());
assertEquals(1, docsOnly.freq());
assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
// reuse that too
PostingsEnum docsOnly2 = termsEnum.postings(null, docsOnly, PostingsEnum.NONE);
assertNotNull(docsOnly2);
assertSame(docsOnly, docsOnly2);
// and it had better work
assertEquals(-1, docsOnly2.docID());
assertEquals(0, docsOnly2.nextDoc());
assertEquals(1, docsOnly2.freq());
assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly2.nextDoc());
// we did not index positions
PostingsEnum docsAndPositionsEnum = getOnlySegmentReader(reader).postings(new Term("foo", "bar"), PostingsEnum.POSITIONS);
assertNull(docsAndPositionsEnum);
// we did not index positions
docsAndPositionsEnum = getOnlySegmentReader(reader).postings(new Term("foo", "bar"), PostingsEnum.PAYLOADS);
assertNull(docsAndPositionsEnum);
// we did not index positions
docsAndPositionsEnum = getOnlySegmentReader(reader).postings(new Term("foo", "bar"), PostingsEnum.OFFSETS);
assertNull(docsAndPositionsEnum);
// we did not index positions
docsAndPositionsEnum = getOnlySegmentReader(reader).postings(new Term("foo", "bar"), PostingsEnum.ALL);
assertNull(docsAndPositionsEnum);
iw.close();
reader.close();
dir.close();
}
}

View File

@ -114,14 +114,22 @@ public class AssertingLeafReader extends FilterLeafReader {
@Override
public TermsEnum iterator(TermsEnum reuse) throws IOException {
// TODO: should we give this thing a random to be super-evil,
// and randomly *not* unwrap?
// reuse, if the codec reused
final TermsEnum actualReuse;
if (reuse instanceof AssertingTermsEnum) {
reuse = ((AssertingTermsEnum) reuse).in;
actualReuse = ((AssertingTermsEnum) reuse).in;
} else {
actualReuse = null;
}
TermsEnum termsEnum = super.iterator(reuse);
TermsEnum termsEnum = super.iterator(actualReuse);
assert termsEnum != null;
return new AssertingTermsEnum(termsEnum);
if (termsEnum == actualReuse) {
// codec reused, reset asserting state
((AssertingTermsEnum)reuse).reset();
return reuse;
} else {
return new AssertingTermsEnum(termsEnum);
}
}
}
@ -143,13 +151,23 @@ public class AssertingLeafReader extends FilterLeafReader {
assertThread("Terms enums", creationThread);
assert state == State.POSITIONED: "docs(...) called on unpositioned TermsEnum";
// TODO: should we give this thing a random to be super-evil,
// and randomly *not* unwrap?
// reuse if the codec reused
final PostingsEnum actualReuse;
if (reuse instanceof AssertingPostingsEnum) {
reuse = ((AssertingPostingsEnum) reuse).in;
actualReuse = ((AssertingPostingsEnum) reuse).in;
} else {
actualReuse = null;
}
PostingsEnum docs = super.postings(liveDocs, actualReuse, flags);
if (docs == null) {
return null;
} else if (docs == actualReuse) {
// codec reused, reset asserting state
((AssertingPostingsEnum)reuse).reset();
return reuse;
} else {
return new AssertingPostingsEnum(docs);
}
PostingsEnum docs = super.postings(liveDocs, reuse, flags);
return docs == null ? null : new AssertingPostingsEnum(docs);
}
// TODO: we should separately track if we are 'at the end' ?
@ -255,6 +273,10 @@ public class AssertingLeafReader extends FilterLeafReader {
public String toString() {
return "AssertingTermsEnum(" + in + ")";
}
void reset() {
state = State.INITIAL;
}
}
static enum DocsEnumState { START, ITERATING, FINISHED };
@ -362,6 +384,12 @@ public class AssertingLeafReader extends FilterLeafReader {
assert payload == null || payload.length > 0 : "getPayload() returned payload with invalid length!";
return payload;
}
void reset() {
state = DocsEnumState.START;
doc = in.docID();
positionCount = positionMax = 0;
}
}
/** Wraps a NumericDocValues but with additional asserts */