You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2015/02/17 21:21:55 UTC
svn commit: r1660489 - in /lucene/dev/branches/branch_5x/lucene/core/src:
java/org/apache/lucene/index/ test/org/apache/lucene/index/
Author: rmuir
Date: Tue Feb 17 20:21:54 2015
New Revision: 1660489
URL: http://svn.apache.org/r1660489
Log:
LUCENE-6246: add backwards layer
Added:
lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsAndPositionsEnum.java (with props)
lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsEnum.java (with props)
lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestLegacyPostings.java (with props)
Modified:
lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java
lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
Added: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsAndPositionsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsAndPositionsEnum.java?rev=1660489&view=auto
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsAndPositionsEnum.java (added)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsAndPositionsEnum.java Tue Feb 17 20:21:54 2015
@@ -0,0 +1,148 @@
+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 java.io.IOException;
+import java.util.Objects;
+
+import org.apache.lucene.util.AttributeSource;
+import org.apache.lucene.util.Bits; // javadocs
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Also iterates through positions.
+ * @deprecated Use {@link PostingsEnum} instead.
+ */
+@Deprecated
+public abstract class DocsAndPositionsEnum extends DocsEnum {
+
+ /** Flag to pass to {@link TermsEnum#docsAndPositions(Bits,DocsAndPositionsEnum,int)}
+ * if you require offsets in the returned enum. */
+ public static final int FLAG_OFFSETS = 0x1;
+
+ /** Flag to pass to {@link TermsEnum#docsAndPositions(Bits,DocsAndPositionsEnum,int)}
+ * if you require payloads in the returned enum. */
+ public static final int FLAG_PAYLOADS = 0x2;
+
+ /** Sole constructor. (For invocation by subclass
+ * constructors, typically implicit.) */
+ protected DocsAndPositionsEnum() {
+ }
+
+ /** Returns the next position. You should only call this
+ * up to {@link DocsEnum#freq()} times else
+ * the behavior is not defined. If positions were not
+ * indexed this will return -1; this only happens if
+ * offsets were indexed and you passed needsOffset=true
+ * when pulling the enum. */
+ public abstract int nextPosition() throws IOException;
+
+ /** Returns start offset for the current position, or -1
+ * if offsets were not indexed. */
+ public abstract int startOffset() throws IOException;
+
+ /** Returns end offset for the current position, or -1 if
+ * offsets were not indexed. */
+ public abstract int endOffset() throws IOException;
+
+ /** Returns the payload at this position, or null if no
+ * payload was indexed. You should not modify anything
+ * (neither members of the returned BytesRef nor bytes
+ * in the byte[]). */
+ public abstract BytesRef getPayload() throws IOException;
+
+ /**
+ * Wraps a PostingsEnum with a legacy DocsAndPositionsEnum.
+ */
+ static DocsAndPositionsEnum wrap(final PostingsEnum postings) {
+ return new DocsAndPositionsEnumWrapper(postings);
+ }
+
+ /**
+ * Unwrap a legacy DocsAndPositionsEnum and return the actual PostingsEnum.
+ * if {@code docs} is null, this returns null for convenience
+ */
+ static PostingsEnum unwrap(final DocsEnum docs) {
+ if (docs instanceof DocsAndPositionsEnumWrapper) {
+ return ((DocsAndPositionsEnumWrapper)docs).in;
+ } else if (docs == null) {
+ return null; // e.g. user is not reusing
+ } else {
+ throw new AssertionError();
+ }
+ }
+
+ static class DocsAndPositionsEnumWrapper extends DocsAndPositionsEnum {
+ final PostingsEnum in;
+
+ DocsAndPositionsEnumWrapper(PostingsEnum in) {
+ this.in = Objects.requireNonNull(in);
+ }
+
+ @Override
+ public int nextPosition() throws IOException {
+ return in.nextPosition();
+ }
+
+ @Override
+ public int startOffset() throws IOException {
+ return in.startOffset();
+ }
+
+ @Override
+ public int endOffset() throws IOException {
+ return in.endOffset();
+ }
+
+ @Override
+ public BytesRef getPayload() throws IOException {
+ return in.getPayload();
+ }
+
+ @Override
+ public int freq() throws IOException {
+ return in.freq();
+ }
+
+ @Override
+ public AttributeSource attributes() {
+ return in.attributes();
+ }
+
+ @Override
+ public int docID() {
+ return in.docID();
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ return in.nextDoc();
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ return in.advance(target);
+ }
+
+ @Override
+ public long cost() {
+ return in.cost();
+ }
+ }
+}
+
Added: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsEnum.java?rev=1660489&view=auto
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsEnum.java (added)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/DocsEnum.java Tue Feb 17 20:21:54 2015
@@ -0,0 +1,70 @@
+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 java.io.IOException;
+
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * Iterates through the documents and term freqs.
+ * NOTE: you must first call {@link #nextDoc} before using
+ * any of the per-doc methods.
+ * @deprecated Use {@link PostingsEnum} instead.
+ */
+@Deprecated
+public abstract class DocsEnum extends PostingsEnum {
+
+ /**
+ * Flag to pass to {@link TermsEnum#docs(Bits,DocsEnum,int)} if you don't
+ * require term frequencies in the returned enum. When passed to
+ * {@link TermsEnum#docsAndPositions(Bits,DocsAndPositionsEnum,int)} means
+ * that no offsets and payloads will be returned.
+ */
+ public static final int FLAG_NONE = 0x0;
+
+ /** Flag to pass to {@link TermsEnum#docs(Bits,DocsEnum,int)}
+ * if you require term frequencies in the returned enum. */
+ public static final int FLAG_FREQS = 0x1;
+
+ /** Sole constructor. (For invocation by subclass
+ * constructors, typically implicit.) */
+ protected DocsEnum() {
+ }
+
+ @Override
+ public int nextPosition() throws IOException {
+ return -1;
+ }
+
+ @Override
+ public int startOffset() throws IOException {
+ return -1;
+ }
+
+ @Override
+ public int endOffset() throws IOException {
+ return -1;
+ }
+
+ @Override
+ public BytesRef getPayload() throws IOException {
+ return null;
+ }
+}
Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java?rev=1660489&r1=1660488&r2=1660489&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/LeafReader.java Tue Feb 17 20:21:54 2015
@@ -297,4 +297,40 @@ public abstract class LeafReader extends
* @lucene.internal
*/
public abstract void checkIntegrity() throws IOException;
+
+ /** Returns {@link DocsEnum} for the specified term.
+ * This will return null if either the field or
+ * term does not exist.
+ * @deprecated use {@link #postings(Term)} instead */
+ @Deprecated
+ public final DocsEnum termDocsEnum(Term term) throws IOException {
+ assert term.field() != null;
+ assert term.bytes() != null;
+ final Terms terms = terms(term.field());
+ if (terms != null) {
+ final TermsEnum termsEnum = terms.iterator(null);
+ if (termsEnum.seekExact(term.bytes())) {
+ return termsEnum.docs(getLiveDocs(), null);
+ }
+ }
+ return null;
+ }
+
+ /** Returns {@link DocsAndPositionsEnum} for the specified
+ * term. This will return null if the
+ * field or term does not exist or positions weren't indexed.
+ * @deprecated use {@link #postings(Term, int)} instead */
+ @Deprecated
+ public final DocsAndPositionsEnum termPositionsEnum(Term term) throws IOException {
+ assert term.field() != null;
+ assert term.bytes() != null;
+ final Terms terms = terms(term.field());
+ if (terms != null) {
+ final TermsEnum termsEnum = terms.iterator(null);
+ if (termsEnum.seekExact(term.bytes())) {
+ return termsEnum.docsAndPositions(getLiveDocs(), null);
+ }
+ }
+ return null;
+ }
}
Modified: lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java?rev=1660489&r1=1660488&r2=1660489&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java (original)
+++ lucene/dev/branches/branch_5x/lucene/core/src/java/org/apache/lucene/index/TermsEnum.java Tue Feb 17 20:21:54 2015
@@ -243,4 +243,104 @@ public abstract class TermsEnum implemen
}
};
+
+ /** Get {@link DocsEnum} for the current term. Do not
+ * call this when the enum is unpositioned. This method
+ * will not return null.
+ *
+ * @param liveDocs unset bits are documents that should not
+ * be returned
+ * @param reuse pass a prior DocsEnum for possible reuse
+ * @deprecated Use {@link #postings(Bits, PostingsEnum)} instead */
+ @Deprecated
+ public final DocsEnum docs(Bits liveDocs, DocsEnum reuse) throws IOException {
+ return docs(liveDocs, reuse, DocsEnum.FLAG_FREQS);
+ }
+
+ /** Get {@link DocsEnum} for the current term, with
+ * control over whether freqs are required. Do not
+ * call this when the enum is unpositioned. This method
+ * will not return null.
+ *
+ * @param liveDocs unset bits are documents that should not
+ * be returned
+ * @param reuse pass a prior DocsEnum for possible reuse
+ * @param flags specifies which optional per-document values
+ * you require; see {@link DocsEnum#FLAG_FREQS}
+ * @see #docs(Bits, DocsEnum, int)
+ * @deprecated Use {@link #postings(Bits, PostingsEnum, int)} instead */
+ @Deprecated
+ public final DocsEnum docs(Bits liveDocs, DocsEnum reuse, int flags) throws IOException {
+ final int newFlags;
+ if (flags == DocsEnum.FLAG_FREQS) {
+ newFlags = PostingsEnum.FREQS;
+ } else if (flags == DocsEnum.FLAG_NONE) {
+ newFlags = PostingsEnum.NONE;
+ } else {
+ throw new IllegalArgumentException("Invalid legacy docs flags: " + flags);
+ }
+ PostingsEnum actualReuse = DocsAndPositionsEnum.unwrap(reuse);
+ PostingsEnum postings = postings(liveDocs, actualReuse, newFlags);
+ if (postings == null) {
+ throw new AssertionError();
+ } else if (postings == actualReuse) {
+ return reuse;
+ } else {
+ return DocsAndPositionsEnum.wrap(postings);
+ }
+ };
+
+ /** Get {@link DocsAndPositionsEnum} for the current term.
+ * Do not call this when the enum is unpositioned. This
+ * method will return null if positions were not
+ * indexed.
+ *
+ * @param liveDocs unset bits are documents that should not
+ * be returned
+ * @param reuse pass a prior DocsAndPositionsEnum for possible reuse
+ * @see #docsAndPositions(Bits, DocsAndPositionsEnum, int)
+ * @deprecated Use {@link #postings(Bits, PostingsEnum, int)} instead */
+ @Deprecated
+ public final DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse) throws IOException {
+ return docsAndPositions(liveDocs, reuse, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ }
+
+ /** Get {@link DocsAndPositionsEnum} for the current term,
+ * with control over whether offsets and payloads are
+ * required. Some codecs may be able to optimize their
+ * implementation when offsets and/or payloads are not required.
+ * Do not call this when the enum is unpositioned. This
+ * will return null if positions were not indexed.
+
+ * @param liveDocs unset bits are documents that should not
+ * be returned
+ * @param reuse pass a prior DocsAndPositionsEnum for possible reuse
+ * @param flags specifies which optional per-position values you
+ * require; see {@link DocsAndPositionsEnum#FLAG_OFFSETS} and
+ * {@link DocsAndPositionsEnum#FLAG_PAYLOADS}.
+ * @deprecated Use {@link #postings(Bits, PostingsEnum, int)} instead */
+ @Deprecated
+ public final DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, int flags) throws IOException {
+ final int newFlags;
+ if (flags == (DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS)) {
+ newFlags = PostingsEnum.OFFSETS | PostingsEnum.PAYLOADS;
+ } else if (flags == DocsAndPositionsEnum.FLAG_OFFSETS) {
+ newFlags = PostingsEnum.OFFSETS;
+ } else if (flags == DocsAndPositionsEnum.FLAG_PAYLOADS) {
+ newFlags = PostingsEnum.PAYLOADS;
+ } else if (flags == DocsAndPositionsEnum.FLAG_NONE) {
+ newFlags = PostingsEnum.POSITIONS;
+ } else {
+ throw new IllegalArgumentException("Invalid legacy docsAndPositions flags: " + flags);
+ }
+ PostingsEnum actualReuse = DocsAndPositionsEnum.unwrap(reuse);
+ PostingsEnum postings = postings(liveDocs, actualReuse, newFlags);
+ if (postings == null) {
+ return null; // if no positions were indexed
+ } else if (postings == actualReuse) {
+ return reuse;
+ } else {
+ return DocsAndPositionsEnum.wrap(postings);
+ }
+ }
}
Added: lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestLegacyPostings.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestLegacyPostings.java?rev=1660489&view=auto
==============================================================================
--- lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestLegacyPostings.java (added)
+++ lucene/dev/branches/branch_5x/lucene/core/src/test/org/apache/lucene/index/TestLegacyPostings.java Tue Feb 17 20:21:54 2015
@@ -0,0 +1,933 @@
+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.analysis.Analyzer;
+import org.apache.lucene.analysis.CannedTokenStream;
+import org.apache.lucene.analysis.MockTokenizer;
+import org.apache.lucene.analysis.Token;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
+
+/**
+ * Test old postings api (DocsEnum, DocsAndPositionsEnum, etc)
+ * @deprecated only for testing backwards compat cruft
+ */
+@SuppressCodecs("Direct") // Direct does not support reuse, but we test that it works...
+@Deprecated
+public class TestLegacyPostings 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)
+ DocsEnum postings = getOnlySegmentReader(reader).termDocsEnum(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"));
+ DocsEnum postings2 = termsEnum.docs(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
+ DocsEnum docsOnly = termsEnum.docs(null, null, DocsEnum.FLAG_NONE);
+ assertEquals(-1, docsOnly.docID());
+ assertEquals(0, docsOnly.nextDoc());
+ assertEquals(1, docsOnly.freq());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
+ // reuse that too
+ DocsEnum docsOnly2 = termsEnum.docs(null, docsOnly, DocsEnum.FLAG_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());
+
+ // sugar method: we did not index positions
+ DocsAndPositionsEnum docsAndPositionsEnum = getOnlySegmentReader(reader).termPositionsEnum(new Term("foo", "bar"));
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null);
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS | DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNull(docsAndPositionsEnum);
+
+ iw.close();
+ reader.close();
+ dir.close();
+ }
+
+ public void testFreqs() throws Exception {
+ Directory dir = newDirectory();
+ IndexWriterConfig iwc = new IndexWriterConfig(new Analyzer() {
+ @Override
+ protected TokenStreamComponents createComponents(String fieldName) {
+ return new TokenStreamComponents(new MockTokenizer());
+ }
+ });
+ IndexWriter iw = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
+ ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS);
+ doc.add(new Field("foo", "bar bar", ft));
+ iw.addDocument(doc);
+ DirectoryReader reader = DirectoryReader.open(iw, false);
+
+ // sugar method (FREQS)
+ DocsEnum postings = getOnlySegmentReader(reader).termDocsEnum(new Term("foo", "bar"));
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, 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"));
+ DocsEnum postings2 = termsEnum.docs(null, postings);
+ assertNotNull(postings2);
+ assertSame(postings, postings2);
+ // and it had better work
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, postings.freq());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
+
+ // asking for docs only: ok
+ DocsEnum docsOnly = termsEnum.docs(null, null, DocsEnum.FLAG_NONE);
+ assertEquals(-1, docsOnly.docID());
+ assertEquals(0, docsOnly.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
+ // reuse that too
+ DocsEnum docsOnly2 = termsEnum.docs(null, docsOnly, DocsEnum.FLAG_NONE);
+ assertNotNull(docsOnly2);
+ assertSame(docsOnly, docsOnly2);
+ // and it had better work
+ assertEquals(-1, docsOnly2.docID());
+ assertEquals(0, docsOnly2.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly2.nextDoc());
+
+ // sugar method: we did not index positions
+ DocsAndPositionsEnum docsAndPositionsEnum = getOnlySegmentReader(reader).termPositionsEnum(new Term("foo", "bar"));
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null);
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNull(docsAndPositionsEnum);
+
+ // we did not index positions
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS | DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNull(docsAndPositionsEnum);
+
+ iw.close();
+ reader.close();
+ dir.close();
+ }
+
+ public void testPositions() throws Exception {
+ Directory dir = newDirectory();
+ IndexWriterConfig iwc = new IndexWriterConfig(new Analyzer() {
+ @Override
+ protected TokenStreamComponents createComponents(String fieldName) {
+ return new TokenStreamComponents(new MockTokenizer());
+ }
+ });
+ IndexWriter iw = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ doc.add(new TextField("foo", "bar bar", Field.Store.NO));
+ iw.addDocument(doc);
+ DirectoryReader reader = DirectoryReader.open(iw, false);
+
+ // sugar method (FREQS)
+ DocsEnum postings = getOnlySegmentReader(reader).termDocsEnum(new Term("foo", "bar"));
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, 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"));
+ DocsEnum postings2 = termsEnum.docs(null, postings);
+ assertNotNull(postings2);
+ assertSame(postings, postings2);
+ // and it had better work
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, postings.freq());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
+
+ // asking for docs only: ok
+ DocsEnum docsOnly = termsEnum.docs(null, null, DocsEnum.FLAG_NONE);
+ assertEquals(-1, docsOnly.docID());
+ assertEquals(0, docsOnly.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
+ // reuse that too
+ DocsEnum docsOnly2 = termsEnum.docs(null, docsOnly, DocsEnum.FLAG_NONE);
+ assertNotNull(docsOnly2);
+ assertSame(docsOnly, docsOnly2);
+ // and it had better work
+ assertEquals(-1, docsOnly2.docID());
+ assertEquals(0, docsOnly2.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly2.nextDoc());
+
+ // asking for positions, ok
+ DocsAndPositionsEnum docsAndPositionsEnum = getOnlySegmentReader(reader).termPositionsEnum(new Term("foo", "bar"));
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // now reuse the positions
+ DocsAndPositionsEnum docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // payloads, offsets, etc don't cause an error if they aren't there
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ // but make sure they work
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS | DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_PAYLOADS | DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ iw.close();
+ reader.close();
+ dir.close();
+ }
+
+ public void testOffsets() throws Exception {
+ Directory dir = newDirectory();
+ IndexWriterConfig iwc = new IndexWriterConfig(new Analyzer() {
+ @Override
+ protected TokenStreamComponents createComponents(String fieldName) {
+ return new TokenStreamComponents(new MockTokenizer());
+ }
+ });
+ IndexWriter iw = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
+ ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
+ doc.add(new Field("foo", "bar bar", ft));
+ iw.addDocument(doc);
+ DirectoryReader reader = DirectoryReader.open(iw, false);
+
+ // sugar method (FREQS)
+ DocsEnum postings = getOnlySegmentReader(reader).termDocsEnum(new Term("foo", "bar"));
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, 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"));
+ DocsEnum postings2 = termsEnum.docs(null, postings);
+ assertNotNull(postings2);
+ assertSame(postings, postings2);
+ // and it had better work
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, postings.freq());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
+
+ // asking for docs only: ok
+ DocsEnum docsOnly = termsEnum.docs(null, null, DocsEnum.FLAG_NONE);
+ assertEquals(-1, docsOnly.docID());
+ assertEquals(0, docsOnly.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
+ // reuse that too
+ DocsEnum docsOnly2 = termsEnum.docs(null, docsOnly, DocsEnum.FLAG_NONE);
+ assertNotNull(docsOnly2);
+ assertSame(docsOnly, docsOnly2);
+ // and it had better work
+ assertEquals(-1, docsOnly2.docID());
+ assertEquals(0, docsOnly2.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly2.nextDoc());
+
+ // asking for positions, ok
+ DocsAndPositionsEnum docsAndPositionsEnum = getOnlySegmentReader(reader).termPositionsEnum(new Term("foo", "bar"));
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // now reuse the positions
+ DocsAndPositionsEnum docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // payloads don't cause an error if they aren't there
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ // but make sure they work
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ assertNull(docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ iw.close();
+ reader.close();
+ dir.close();
+ }
+
+ public void testPayloads() throws Exception {
+ Directory dir = newDirectory();
+ IndexWriterConfig iwc = new IndexWriterConfig(null);
+ IndexWriter iw = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ Token token1 = new Token("bar", 0, 3);
+ token1.setPayload(new BytesRef("pay1"));
+ Token token2 = new Token("bar", 4, 7);
+ token2.setPayload(new BytesRef("pay2"));
+ doc.add(new TextField("foo", new CannedTokenStream(token1, token2)));
+ iw.addDocument(doc);
+ DirectoryReader reader = DirectoryReader.open(iw, false);
+
+ // sugar method (FREQS)
+ DocsEnum postings = getOnlySegmentReader(reader).termDocsEnum(new Term("foo", "bar"));
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, 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"));
+ DocsEnum postings2 = termsEnum.docs(null, postings);
+ assertNotNull(postings2);
+ assertSame(postings, postings2);
+ // and it had better work
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, postings.freq());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
+
+ // asking for docs only: ok
+ DocsEnum docsOnly = termsEnum.docs(null, null, DocsEnum.FLAG_NONE);
+ assertEquals(-1, docsOnly.docID());
+ assertEquals(0, docsOnly.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
+ // reuse that too
+ DocsEnum docsOnly2 = termsEnum.docs(null, docsOnly, DocsEnum.FLAG_NONE);
+ assertNotNull(docsOnly2);
+ assertSame(docsOnly, docsOnly2);
+ // and it had better work
+ assertEquals(-1, docsOnly2.docID());
+ assertEquals(0, docsOnly2.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly2.nextDoc());
+
+ // asking for positions, ok
+ DocsAndPositionsEnum docsAndPositionsEnum = termsEnum.docsAndPositions(null, null);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // now reuse the positions
+ DocsAndPositionsEnum docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // payloads
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(-1, docsAndPositionsEnum.startOffset());
+ assertEquals(-1, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ iw.close();
+ reader.close();
+ dir.close();
+ }
+
+ public void testAll() throws Exception {
+ Directory dir = newDirectory();
+ IndexWriterConfig iwc = new IndexWriterConfig(null);
+ IndexWriter iw = new IndexWriter(dir, iwc);
+ Document doc = new Document();
+ Token token1 = new Token("bar", 0, 3);
+ token1.setPayload(new BytesRef("pay1"));
+ Token token2 = new Token("bar", 4, 7);
+ token2.setPayload(new BytesRef("pay2"));
+ FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
+ ft.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
+ doc.add(new Field("foo", new CannedTokenStream(token1, token2), ft));
+ iw.addDocument(doc);
+ DirectoryReader reader = DirectoryReader.open(iw, false);
+
+ // sugar method (FREQS)
+ DocsEnum postings = getOnlySegmentReader(reader).termDocsEnum(new Term("foo", "bar"));
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, 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"));
+ DocsEnum postings2 = termsEnum.docs(null, postings);
+ assertNotNull(postings2);
+ assertSame(postings, postings2);
+ // and it had better work
+ assertEquals(-1, postings.docID());
+ assertEquals(0, postings.nextDoc());
+ assertEquals(2, postings.freq());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, postings.nextDoc());
+
+ // asking for docs only: ok
+ DocsEnum docsOnly = termsEnum.docs(null, null, DocsEnum.FLAG_NONE);
+ assertEquals(-1, docsOnly.docID());
+ assertEquals(0, docsOnly.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly.nextDoc());
+ // reuse that too
+ DocsEnum docsOnly2 = termsEnum.docs(null, docsOnly, DocsEnum.FLAG_NONE);
+ assertNotNull(docsOnly2);
+ assertSame(docsOnly, docsOnly2);
+ // and it had better work
+ assertEquals(-1, docsOnly2.docID());
+ assertEquals(0, docsOnly2.nextDoc());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsOnly.freq() == 1 || docsOnly.freq() == 2);
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsOnly2.nextDoc());
+
+ // asking for positions, ok
+ DocsAndPositionsEnum docsAndPositionsEnum = getOnlySegmentReader(reader).termPositionsEnum(new Term("foo", "bar"));
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // now reuse the positions
+ DocsAndPositionsEnum docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ // payloads
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 0);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 3);
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.startOffset() == -1 || docsAndPositionsEnum.startOffset() == 4);
+ assertTrue(docsAndPositionsEnum.endOffset() == -1 || docsAndPositionsEnum.endOffset() == 7);
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ // reuse
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay1").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ // we don't define what it is, but if its something else, we should look into it?
+ assertTrue(docsAndPositionsEnum.getPayload() == null || new BytesRef("pay2").equals(docsAndPositionsEnum.getPayload()));
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ docsAndPositionsEnum = termsEnum.docsAndPositions(null, null, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertNotNull(docsAndPositionsEnum);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+ docsAndPositionsEnum2 = termsEnum.docsAndPositions(null, docsAndPositionsEnum, DocsAndPositionsEnum.FLAG_OFFSETS | DocsAndPositionsEnum.FLAG_PAYLOADS);
+ assertSame(docsAndPositionsEnum, docsAndPositionsEnum2);
+ assertEquals(-1, docsAndPositionsEnum.docID());
+ assertEquals(0, docsAndPositionsEnum.nextDoc());
+ assertEquals(2, docsAndPositionsEnum.freq());
+ assertEquals(0, docsAndPositionsEnum.nextPosition());
+ assertEquals(0, docsAndPositionsEnum.startOffset());
+ assertEquals(3, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay1"), docsAndPositionsEnum.getPayload());
+ assertEquals(1, docsAndPositionsEnum.nextPosition());
+ assertEquals(4, docsAndPositionsEnum.startOffset());
+ assertEquals(7, docsAndPositionsEnum.endOffset());
+ assertEquals(new BytesRef("pay2"), docsAndPositionsEnum.getPayload());
+ assertEquals(DocIdSetIterator.NO_MORE_DOCS, docsAndPositionsEnum.nextDoc());
+
+ iw.close();
+ reader.close();
+ dir.close();
+ }
+}