LUCENE-4924: DocIdSetIterator.docID() must return -1 when the iterator is not positioned.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1468083 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrien Grand 2013-04-15 14:08:02 +00:00
parent 9431cb06bd
commit 924e299014
13 changed files with 82 additions and 69 deletions

View File

@ -19,6 +19,10 @@ Changes in backwards compatibility policy
(Nikola Tanković, Uwe Schindler, Chris Male, Mike McCandless,
Robert Muir)
* LUCENE-4924: DocIdSetIterator.docID() must now return -1 when the iterator is
not positioned. This change affects all classes that inherit from
DocIdSetIterator, including DocsEnum and DocsAndPositionsEnum. (Adrien Grand)
New Features
* LUCENE-4747: Move to Java 7 as minimum Java version.

View File

@ -29,20 +29,36 @@ public abstract class DocIdSet {
/** An empty {@code DocIdSet} instance for easy use, e.g. in Filters that hit no documents. */
public static final DocIdSet EMPTY_DOCIDSET = new DocIdSet() {
private final DocIdSetIterator iterator = new DocIdSetIterator() {
@Override
public int advance(int target) { return NO_MORE_DOCS; }
@Override
public int docID() { return NO_MORE_DOCS; }
@Override
public int nextDoc() { return NO_MORE_DOCS; }
@Override
public long cost() { return 0; }
};
@Override
public DocIdSetIterator iterator() {
return iterator;
return new DocIdSetIterator() {
boolean exhausted = false;
@Override
public int advance(int target) {
assert !exhausted;
assert target >= 0;
exhausted = true;
return NO_MORE_DOCS;
}
@Override
public int docID() {
return exhausted ? NO_MORE_DOCS : -1;
}
@Override
public int nextDoc() {
assert !exhausted;
exhausted = true;
return NO_MORE_DOCS;
}
@Override
public long cost() {
return 0;
}
};
}
@Override
@ -56,7 +72,7 @@ public abstract class DocIdSet {
return null;
}
};
/** Provides a {@link DocIdSetIterator} to access the set.
* This implementation can return <code>null</code> or
* <code>{@linkplain #EMPTY_DOCIDSET}.iterator()</code> if there

View File

@ -37,7 +37,7 @@ public abstract class DocIdSetIterator {
/**
* Returns the following:
* <ul>
* <li>-1 or {@link #NO_MORE_DOCS} if {@link #nextDoc()} or
* <li><code>-1</code> if {@link #nextDoc()} or
* {@link #advance(int)} were not called yet.
* <li>{@link #NO_MORE_DOCS} if the iterator has exhausted.
* <li>Otherwise it should return the doc ID it is currently on.
@ -96,8 +96,7 @@ public abstract class DocIdSetIterator {
/** Slow (linear) implementation of {@link #advance} relying on
* {@link #nextDoc()} to advance beyond the target position. */
protected final int slowAdvance(int target) throws IOException {
assert docID() == NO_MORE_DOCS // can happen when the enum is not positioned yet
|| docID() < target;
assert docID() < target;
int doc;
do {
doc = nextDoc();

View File

@ -58,7 +58,7 @@ public abstract class Scorer extends DocsEnum {
* @param collector The collector to which all matching documents are passed.
*/
public void score(Collector collector) throws IOException {
assert docID() == -1 || docID() == NO_MORE_DOCS; // not started
assert docID() == -1; // not started
collector.setScorer(this);
int doc;
while ((doc = nextDoc()) != NO_MORE_DOCS) {

View File

@ -42,12 +42,8 @@ public class SpanScorer extends Scorer {
this.docScorer = docScorer;
this.spans = spans;
if (this.spans.next()) {
doc = -1;
} else {
doc = NO_MORE_DOCS;
more = false;
}
doc = -1;
more = spans.next();
}
@Override

View File

@ -394,8 +394,8 @@ public class TestBlockPostingsFormat3 extends LuceneTestCase {
assertNull(rightDocs);
return;
}
assertTrue(leftDocs.docID() == -1 || leftDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertTrue(rightDocs.docID() == -1 || rightDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, leftDocs.docID());
assertEquals(-1, rightDocs.docID());
int docid;
while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
assertEquals(docid, rightDocs.nextDoc());
@ -417,8 +417,8 @@ public class TestBlockPostingsFormat3 extends LuceneTestCase {
assertNull(rightDocs);
return;
}
assertTrue(leftDocs.docID() == -1 || leftDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertTrue(rightDocs.docID() == -1 || rightDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, leftDocs.docID());
assertEquals(-1, rightDocs.docID());
int docid;
while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
assertEquals(docid, rightDocs.nextDoc());

View File

@ -336,7 +336,7 @@ public class TestDocsAndPositions extends LuceneTestCase {
AtomicReader r = getOnlySegmentReader(reader);
DocsEnum disi = _TestUtil.docs(random(), r, "foo", new BytesRef("bar"), null, null, DocsEnum.FLAG_NONE);
int docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
// now reuse and check again
@ -344,7 +344,7 @@ public class TestDocsAndPositions extends LuceneTestCase {
assertTrue(te.seekExact(new BytesRef("bar"), true));
disi = _TestUtil.docs(random(), te, null, disi, DocsEnum.FLAG_NONE);
docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
writer.close();
r.close();
@ -361,7 +361,7 @@ public class TestDocsAndPositions extends LuceneTestCase {
AtomicReader r = getOnlySegmentReader(reader);
DocsAndPositionsEnum disi = r.termPositionsEnum(new Term("foo", "bar"));
int docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
// now reuse and check again
@ -369,7 +369,7 @@ public class TestDocsAndPositions extends LuceneTestCase {
assertTrue(te.seekExact(new BytesRef("bar"), true));
disi = te.docsAndPositions(null, disi);
docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
writer.close();
r.close();

View File

@ -229,7 +229,7 @@ public class TestTermVectorsReader extends LuceneTestCase {
docsEnum = _TestUtil.docs(random(), termsEnum, null, docsEnum, DocsEnum.FLAG_NONE);
assertNotNull(docsEnum);
int doc = docsEnum.docID();
assertTrue(doc == -1 || doc == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, doc);
assertTrue(docsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsEnum.nextDoc());
}
@ -256,7 +256,7 @@ public class TestTermVectorsReader extends LuceneTestCase {
dpEnum = termsEnum.docsAndPositions(null, dpEnum);
assertNotNull(dpEnum);
int doc = dpEnum.docID();
assertTrue(doc == -1 || doc == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, doc);
assertTrue(dpEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
assertEquals(dpEnum.freq(), positions[i].length);
for (int j = 0; j < positions[i].length; j++) {
@ -266,7 +266,7 @@ public class TestTermVectorsReader extends LuceneTestCase {
dpEnum = termsEnum.docsAndPositions(null, dpEnum);
doc = dpEnum.docID();
assertTrue(doc == -1 || doc == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, doc);
assertTrue(dpEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
assertNotNull(dpEnum);
assertEquals(dpEnum.freq(), positions[i].length);

View File

@ -193,29 +193,22 @@ class TermsIncludingScoreQuery extends Query {
DocsEnum docsEnum;
DocsEnum reuse;
int scoreUpto;
int doc;
SVInnerScorer(Weight weight, Bits acceptDocs, TermsEnum termsEnum, long cost) {
super(weight);
this.acceptDocs = acceptDocs;
this.termsEnum = termsEnum;
this.cost = cost;
this.doc = -1;
}
@Override
public void score(Collector collector) throws IOException {
score(collector, NO_MORE_DOCS, nextDocOutOfOrder());
}
@Override
public boolean score(Collector collector, int max, int firstDocID)
throws IOException {
assert collector.acceptsDocsOutOfOrder();
collector.setScorer(this);
int doc;
for (doc = firstDocID; doc < max; doc = nextDocOutOfOrder()) {
for (int doc = nextDocOutOfOrder(); doc != NO_MORE_DOCS; doc = nextDocOutOfOrder()) {
collector.collect(doc);
}
return doc != NO_MORE_DOCS;
}
@Override
@ -229,7 +222,7 @@ class TermsIncludingScoreQuery extends Query {
@Override
public int docID() {
return docsEnum != null ? docsEnum.docID() : DocIdSetIterator.NO_MORE_DOCS;
return doc;
}
int nextDocOutOfOrder() throws IOException {
@ -238,13 +231,13 @@ class TermsIncludingScoreQuery extends Query {
if (docId == DocIdSetIterator.NO_MORE_DOCS) {
docsEnum = null;
} else {
return docId;
return doc = docId;
}
}
do {
if (upto == terms.size()) {
return DocIdSetIterator.NO_MORE_DOCS;
return doc = DocIdSetIterator.NO_MORE_DOCS;
}
scoreUpto = upto;
@ -253,7 +246,7 @@ class TermsIncludingScoreQuery extends Query {
}
} while (docsEnum == null);
return docsEnum.nextDoc();
return doc = docsEnum.nextDoc();
}
@Override

View File

@ -323,7 +323,7 @@ public class MemoryIndexTest extends BaseTokenStreamTestCase {
AtomicReader reader = (AtomicReader) memory.createSearcher().getIndexReader();
DocsEnum disi = _TestUtil.docs(random(), reader, "foo", new BytesRef("bar"), null, null, DocsEnum.FLAG_NONE);
int docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
// now reuse and check again
@ -331,7 +331,7 @@ public class MemoryIndexTest extends BaseTokenStreamTestCase {
assertTrue(te.seekExact(new BytesRef("bar"), true));
disi = te.docs(null, disi, DocsEnum.FLAG_NONE);
docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
reader.close();
}
@ -354,7 +354,7 @@ public class MemoryIndexTest extends BaseTokenStreamTestCase {
assertEquals(1, reader.terms("foo").getSumTotalTermFreq());
DocsAndPositionsEnum disi = reader.termPositionsEnum(new Term("foo", "bar"));
int docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
assertEquals(0, disi.nextPosition());
assertEquals(0, disi.startOffset());
@ -365,7 +365,7 @@ public class MemoryIndexTest extends BaseTokenStreamTestCase {
assertTrue(te.seekExact(new BytesRef("bar"), true));
disi = te.docsAndPositions(null, disi);
docid = disi.docID();
assertTrue(docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(-1, docid);
assertTrue(disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
reader.close();
memory.reset();

View File

@ -237,7 +237,7 @@ public class AssertingAtomicReader extends FilterAtomicReader {
super(in);
try {
int docid = in.docID();
assert docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS : in.getClass() + ": invalid initial doc id: " + docid;
assert docid == -1 : in.getClass() + ": invalid initial doc id: " + docid;
} catch (UnsupportedOperationException e) {
if (failOnUnsupportedDocID) {
throw e;
@ -256,7 +256,7 @@ public class AssertingAtomicReader extends FilterAtomicReader {
} else {
state = DocsEnumState.ITERATING;
}
assert docID() == nextDoc;
assert super.docID() == nextDoc;
return doc = nextDoc;
}
@ -271,13 +271,15 @@ public class AssertingAtomicReader extends FilterAtomicReader {
} else {
state = DocsEnumState.ITERATING;
}
assert docID() == advanced;
assert super.docID() == advanced;
return doc = advanced;
}
// NOTE: We don't assert anything for docId(). Specifically DocsEnum javadocs
// are ambiguous with DocIdSetIterator here, DocIdSetIterator says its ok
// to call this method before nextDoc(), just that it must be -1 or NO_MORE_DOCS!
@Override
public int docID() {
assert doc == super.docID() : " invalid docID() in " + in.getClass() + " " + super.docID() + " instead of " + doc;
return doc;
}
@Override
public int freq() throws IOException {
@ -298,7 +300,7 @@ public class AssertingAtomicReader extends FilterAtomicReader {
public AssertingDocsAndPositionsEnum(DocsAndPositionsEnum in) {
super(in);
int docid = in.docID();
assert docid == -1 || docid == DocIdSetIterator.NO_MORE_DOCS : "invalid initial doc id: " + docid;
assert docid == -1 : "invalid initial doc id: " + docid;
doc = -1;
}
@ -315,7 +317,7 @@ public class AssertingAtomicReader extends FilterAtomicReader {
state = DocsEnumState.ITERATING;
positionMax = super.freq();
}
assert docID() == nextDoc;
assert super.docID() == nextDoc;
return doc = nextDoc;
}
@ -333,10 +335,16 @@ public class AssertingAtomicReader extends FilterAtomicReader {
state = DocsEnumState.ITERATING;
positionMax = super.freq();
}
assert docID() == advanced;
assert super.docID() == advanced;
return doc = advanced;
}
@Override
public int docID() {
assert doc == super.docID() : " invalid docID() in " + in.getClass() + " " + super.docID() + " instead of " + doc;
return doc;
}
@Override
public int freq() throws IOException {
assert state != DocsEnumState.START : "freq() called before nextDoc()/advance()";

View File

@ -66,9 +66,6 @@ import org.junit.BeforeClass;
// TODO test when you reuse after skipping a term or two, eg the block reuse case
// TODO hmm contract says .doc() can return NO_MORE_DOCS
// before nextDoc too...?
/* TODO
- threads
- assert doc=-1 before any nextDoc
@ -699,7 +696,7 @@ public abstract class BasePostingsFormatTestCase extends LuceneTestCase {
assertNotNull("null DocsEnum", docsEnum);
int initialDocID = docsEnum.docID();
assertTrue("inital docID should be -1 or NO_MORE_DOCS: " + docsEnum, initialDocID == -1 || initialDocID == DocsEnum.NO_MORE_DOCS);
assertEquals("inital docID should be -1" + docsEnum, -1, initialDocID);
if (VERBOSE) {
if (prevDocsEnum == null) {

View File

@ -1534,8 +1534,8 @@ public abstract class LuceneTestCase extends Assert {
assertNull(rightDocs);
return;
}
assertTrue(info, leftDocs.docID() == -1 || leftDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertTrue(info, rightDocs.docID() == -1 || rightDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(info, -1, leftDocs.docID());
assertEquals(info, -1, rightDocs.docID());
int docid;
while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
assertEquals(info, docid, rightDocs.nextDoc());
@ -1559,8 +1559,8 @@ public abstract class LuceneTestCase extends Assert {
assertNull(rightDocs);
return;
}
assertTrue(info, leftDocs.docID() == -1 || leftDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertTrue(info, rightDocs.docID() == -1 || rightDocs.docID() == DocIdSetIterator.NO_MORE_DOCS);
assertEquals(info, -1, leftDocs.docID());
assertEquals(info, -1, rightDocs.docID());
int docid;
while ((docid = leftDocs.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
assertEquals(info, docid, rightDocs.nextDoc());