LUCENE-2487: IndexReader subclasses must implement flex API

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@951760 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2010-06-05 20:31:36 +00:00
parent a6a9e5fce8
commit 9c034e2b0e
17 changed files with 916 additions and 821 deletions

View File

@ -28,10 +28,8 @@ import java.util.Set;
import org.apache.lucene.analysis.CachingTokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.index.FilterIndexReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.index.memory.MemoryIndex;
import org.apache.lucene.search.*;
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
@ -153,7 +151,10 @@ public class WeightedSpanTermExtractor {
if (mtq.getField() != null) {
IndexReader ir = getReaderForField(mtq.getField());
extract(query.rewrite(ir), terms);
} else {
}
// nocommit is this needed anymore?
/*
else {
FakeReader fReader = new FakeReader();
MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE.rewrite(fReader, mtq);
if (fReader.field != null) {
@ -161,6 +162,7 @@ public class WeightedSpanTermExtractor {
extract(query.rewrite(ir), terms);
}
}
*/
} else if (query instanceof MultiPhraseQuery) {
final MultiPhraseQuery mpq = (MultiPhraseQuery) query;
final List<Term[]> termArrays = mpq.getTermArrays();
@ -554,32 +556,4 @@ public class WeightedSpanTermExtractor {
public void setWrapIfNotCachingTokenFilter(boolean wrap) {
this.wrapToCaching = wrap;
}
/**
*
* A fake IndexReader class to extract the field from a MultiTermQuery
*
*/
static final class FakeReader extends FilterIndexReader {
private static final IndexReader EMPTY_MEMORY_INDEX_READER =
new MemoryIndex().createSearcher().getIndexReader();
String field;
FakeReader() {
super(EMPTY_MEMORY_INDEX_READER);
}
@Override
public TermEnum terms(final Term t) throws IOException {
// only set first fieldname, maybe use a Set?
if (t != null && field == null)
field = t.field();
return super.terms(t);
}
}
}

View File

@ -0,0 +1,99 @@
package org.apache.lucene.store.instantiated;
/**
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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.index.DocsAndPositionsEnum;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import java.util.Arrays;
public class InstantiatedDocsAndPositionsEnum extends DocsAndPositionsEnum {
private int upto;
private int posUpto;
private Bits skipDocs;
private InstantiatedTerm term;
protected InstantiatedTermDocumentInformation currentDoc;
private final BytesRef payload = new BytesRef();
public InstantiatedDocsAndPositionsEnum reset(Bits skipDocs, InstantiatedTerm term) {
this.skipDocs = skipDocs;
this.term = term;
upto = -1;
return this;
}
@Override
public int docID() {
return currentDoc.getDocument().getDocumentNumber();
}
@Override
public int nextDoc() {
upto++;
if (upto >= term.getAssociatedDocuments().length) {
return NO_MORE_DOCS;
} else {
currentDoc = term.getAssociatedDocuments()[upto];
if (skipDocs == null || !skipDocs.get(currentDoc.getDocument().getDocumentNumber())) {
posUpto = -1;
return docID();
} else {
return nextDoc();
}
}
}
@Override
public int advance(int target) {
if (currentDoc.getDocument().getDocumentNumber() >= target) {
return nextDoc();
}
int startOffset = upto >= 0 ? upto : 0;
upto = term.seekCeilingDocumentInformationIndex(target, startOffset);
if (upto == -1) {
return NO_MORE_DOCS;
}
currentDoc = term.getAssociatedDocuments()[upto];
if (skipDocs != null && skipDocs.get(currentDoc.getDocument().getDocumentNumber())) {
return nextDoc();
} else {
posUpto = -1;
return docID();
}
}
@Override
public int freq() {
return currentDoc.getTermPositions().length;
}
public int nextPosition() {
return currentDoc.getTermPositions()[++posUpto];
}
public boolean hasPayload() {
return currentDoc.getPayloads()[posUpto] != null;
}
public BytesRef getPayload() {
payload.bytes = currentDoc.getPayloads()[posUpto];
payload.length = payload.bytes.length;
return payload;
}
}

View File

@ -0,0 +1,79 @@
package org.apache.lucene.store.instantiated;
/**
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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.index.DocsEnum;
import org.apache.lucene.util.Bits;
public class InstantiatedDocsEnum extends DocsEnum {
private int upto;
private Bits skipDocs;
private InstantiatedTerm term;
protected InstantiatedTermDocumentInformation currentDoc;
public InstantiatedDocsEnum reset(Bits skipDocs, InstantiatedTerm term) {
this.skipDocs = skipDocs;
this.term = term;
upto = -1;
return this;
}
@Override
public int docID() {
return currentDoc.getDocument().getDocumentNumber();
}
@Override
public int nextDoc() {
upto++;
if (upto >= term.getAssociatedDocuments().length) {
return NO_MORE_DOCS;
} else {
currentDoc = term.getAssociatedDocuments()[upto];
if (skipDocs == null || !skipDocs.get(currentDoc.getDocument().getDocumentNumber())) {
return docID();
} else {
return nextDoc();
}
}
}
@Override
public int advance(int target) {
if (currentDoc.getDocument().getDocumentNumber() >= target) {
return nextDoc();
}
int startOffset = upto >= 0 ? upto : 0;
upto = term.seekCeilingDocumentInformationIndex(target, startOffset);
if (upto == -1) {
return NO_MORE_DOCS;
}
currentDoc = term.getAssociatedDocuments()[upto];
if (skipDocs != null && skipDocs.get(currentDoc.getDocument().getDocumentNumber())) {
return nextDoc();
} else {
return docID();
}
}
@Override
public int freq() {
return currentDoc.getTermPositions().length;
}
}

View File

@ -26,12 +26,15 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Comparator;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldSelector;
import org.apache.lucene.index.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BitVector;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Bits;
/**
* An InstantiatedIndexReader is not a snapshot in time, it is completely in
@ -98,6 +101,22 @@ public class InstantiatedIndexReader extends IndexReader {
return index;
}
@Override
public Bits getDeletedDocs() {
return new Bits() {
@Override
public boolean get(int n) {
return (index.getDeletedDocuments() != null && index.getDeletedDocuments().get(n))
|| (uncommittedDeletedDocuments != null && uncommittedDeletedDocuments.get(n));
}
@Override
public int length() {
return maxDoc();
}
};
}
private BitVector uncommittedDeletedDocuments;
private Map<String,List<NormUpdate>> uncommittedNormsByFieldNameAndDocumentNumber = null;
@ -394,6 +413,66 @@ public class InstantiatedIndexReader extends IndexReader {
return new InstantiatedTermPositions(this);
}
@Override
public Fields fields() {
return new Fields() {
@Override
public FieldsEnum iterator() {
final InstantiatedTerm[] orderedTerms = getIndex().getOrderedTerms();
return new FieldsEnum() {
int upto = -1;
String currentField;
@Override
public String next() {
do {
upto++;
if (upto >= orderedTerms.length) {
return null;
}
} while(orderedTerms[upto].field() == currentField);
currentField = orderedTerms[upto].field();
return currentField;
}
@Override
public TermsEnum terms() {
return new InstantiatedTermsEnum(orderedTerms, upto, currentField);
}
};
}
@Override
public Terms terms(final String field) {
final InstantiatedTerm[] orderedTerms = getIndex().getOrderedTerms();
int i = Arrays.binarySearch(orderedTerms, new Term(field), InstantiatedTerm.termComparator);
if (i < 0) {
i = -i - 1;
}
if (i >= orderedTerms.length || !orderedTerms[i].field().equals(field)) {
// field does not exist
return null;
}
final int startLoc = i;
return new Terms() {
@Override
public TermsEnum iterator() {
return new InstantiatedTermsEnum(orderedTerms, startLoc, field);
}
@Override
public Comparator<BytesRef> getComparator() {
return BytesRef.getUTF8SortedAsUTF16Comparator();
}
};
}
};
}
@Override
public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException {
InstantiatedDocument doc = getIndex().getDocumentsByNumber()[docNumber];

View File

@ -0,0 +1,129 @@
package org.apache.lucene.store.instantiated;
/**
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.DocsAndPositionsEnum;
import java.util.Arrays;
import java.util.Comparator;
public class InstantiatedTermsEnum extends TermsEnum {
private final String field;
private final InstantiatedTerm[] terms;
private final BytesRef br = new BytesRef();
private final int start;
private int upto;
public InstantiatedTermsEnum(InstantiatedTerm[] terms, int start, String field) {
this.start = start;
upto = start-1;
this.field = field;
this.terms = terms;
}
@Override
public SeekStatus seek(BytesRef text, boolean useCache) {
final Term t = new Term(field, text.utf8ToString());
int loc = Arrays.binarySearch(terms, t, InstantiatedTerm.termComparator);
if (loc < 0) {
upto = -loc - 1;
if (upto >= terms.length) {
return SeekStatus.END;
} else {
br.copy(terms[upto].getTerm().text());
return SeekStatus.NOT_FOUND;
}
} else {
upto = loc;
br.copy(text);
return SeekStatus.FOUND;
}
}
@Override
public SeekStatus seek(long ord) {
upto = start + (int) ord;
if (upto >= terms.length) {
return SeekStatus.END;
}
if (terms[upto].field() == field) {
return SeekStatus.FOUND;
} else {
// make sure field was interned
assert !terms[upto].field().equals(field);
return SeekStatus.END;
}
}
@Override
public BytesRef next() {
upto++;
if (upto >= terms.length) {
return null;
}
if (terms[upto].field() == field) {
br.copy(terms[upto].getTerm().text());
return br;
} else {
// make sure field was interned
assert !terms[upto].field().equals(field);
return null;
}
}
@Override
public BytesRef term() {
return br;
}
@Override
public long ord() {
return upto - start;
}
@Override
public int docFreq() {
return terms[upto].getAssociatedDocuments().length;
}
@Override
public DocsEnum docs(Bits skipDocs, DocsEnum reuse) {
if (reuse == null || !(reuse instanceof InstantiatedDocsEnum)) {
reuse = new InstantiatedDocsEnum();
}
return ((InstantiatedDocsEnum) reuse).reset(skipDocs, terms[upto]);
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) {
if (reuse == null || !(reuse instanceof InstantiatedDocsAndPositionsEnum)) {
reuse = new InstantiatedDocsAndPositionsEnum();
}
return ((InstantiatedDocsAndPositionsEnum) reuse).reset(skipDocs, terms[upto]);
}
@Override
public Comparator<BytesRef> getComparator() {
return BytesRef.getUTF8SortedAsUTF16Comparator();
}
}

View File

@ -37,6 +37,12 @@ import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldSelector;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.index.FieldsEnum;
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.DocsAndPositionsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
@ -53,6 +59,7 @@ import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Similarity;
import org.apache.lucene.store.RAMDirectory; // for javadocs
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.Constants; // for javadocs
/**
@ -746,6 +753,11 @@ public class MemoryIndex implements Serializable {
private Info getInfo(int pos) {
return sortedFields[pos].getValue();
}
@Override
public Bits getDeletedDocs() {
return null;
}
@Override
public int docFreq(Term term) {
@ -761,6 +773,242 @@ public class MemoryIndex implements Serializable {
if (DEBUG) System.err.println("MemoryIndexReader.terms()");
return terms(MATCH_ALL_TERM);
}
@Override
public Fields fields() {
sortFields();
return new Fields() {
@Override
public FieldsEnum iterator() {
return new FieldsEnum() {
int upto = -1;
@Override
public String next() {
upto++;
if (upto >= sortedFields.length) {
return null;
}
return sortedFields[upto].getKey();
}
@Override
public TermsEnum terms() {
return new MemoryTermsEnum(sortedFields[upto].getValue());
}
};
}
@Override
public Terms terms(final String field) {
int i = Arrays.binarySearch(sortedFields, field, termComparator);
if (i < 0) {
return null;
} else {
final Info info = getInfo(i);
info.sortTerms();
return new Terms() {
@Override
public TermsEnum iterator() {
return new MemoryTermsEnum(info);
}
@Override
public Comparator<BytesRef> getComparator() {
return BytesRef.getUTF8SortedAsUTF16Comparator();
}
@Override
public long getUniqueTermCount() {
return info.sortedTerms.length;
}
};
}
}
};
}
private class MemoryTermsEnum extends TermsEnum {
private final Info info;
private final BytesRef br = new BytesRef();
int termUpto = -1;
public MemoryTermsEnum(Info info) {
this.info = info;
info.sortTerms();
}
@Override
public SeekStatus seek(BytesRef text, boolean useCache) {
final String s = text.utf8ToString();
termUpto = Arrays.binarySearch(info.sortedTerms, s, termComparator);
if (termUpto < 0) { // not found; choose successor
termUpto = -termUpto -1;
if (termUpto >= info.sortedTerms.length) {
return SeekStatus.END;
} else {
br.copy(info.sortedTerms[termUpto].getKey());
return SeekStatus.NOT_FOUND;
}
} else {
br.copy(info.sortedTerms[termUpto].getKey());
return SeekStatus.FOUND;
}
}
@Override
public SeekStatus seek(long ord) {
termUpto = (int) ord;
if (ord < info.sortedTerms.length) {
return SeekStatus.FOUND;
} else {
return SeekStatus.END;
}
}
@Override
public BytesRef next() {
termUpto++;
if (termUpto >= info.sortedTerms.length) {
return null;
} else {
br.copy(info.sortedTerms[termUpto].getKey());
return br;
}
}
@Override
public BytesRef term() {
return br;
}
@Override
public long ord() {
return termUpto;
}
@Override
public int docFreq() {
return info.sortedTerms[termUpto].getValue().size();
}
@Override
public DocsEnum docs(Bits skipDocs, DocsEnum reuse) {
if (reuse == null || !(reuse instanceof MemoryDocsEnum)) {
reuse = new MemoryDocsEnum();
}
return ((MemoryDocsEnum) reuse).reset(skipDocs, info.sortedTerms[termUpto].getValue());
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) {
if (reuse == null || !(reuse instanceof MemoryDocsAndPositionsEnum)) {
reuse = new MemoryDocsAndPositionsEnum();
}
return ((MemoryDocsAndPositionsEnum) reuse).reset(skipDocs, info.sortedTerms[termUpto].getValue());
}
@Override
public Comparator<BytesRef> getComparator() {
return BytesRef.getUTF8SortedAsUTF16Comparator();
}
}
private class MemoryDocsEnum extends DocsEnum {
private ArrayIntList positions;
private boolean hasNext;
private Bits skipDocs;
public DocsEnum reset(Bits skipDocs, ArrayIntList positions) {
this.skipDocs = skipDocs;
this.positions = positions;
hasNext = true;
return this;
}
@Override
public int docID() {
return 0;
}
@Override
public int nextDoc() {
if (hasNext && (skipDocs == null || !skipDocs.get(0))) {
hasNext = false;
return 0;
} else {
return NO_MORE_DOCS;
}
}
@Override
public int advance(int target) {
return nextDoc();
}
@Override
public int freq() {
return positions.size();
}
}
private class MemoryDocsAndPositionsEnum extends DocsAndPositionsEnum {
private ArrayIntList positions;
private int posUpto;
private boolean hasNext;
private Bits skipDocs;
public DocsAndPositionsEnum reset(Bits skipDocs, ArrayIntList positions) {
this.skipDocs = skipDocs;
this.positions = positions;
posUpto = 0;
hasNext = true;
return this;
}
@Override
public int docID() {
return 0;
}
@Override
public int nextDoc() {
if (hasNext && (skipDocs == null || !skipDocs.get(0))) {
hasNext = false;
return 0;
} else {
return NO_MORE_DOCS;
}
}
@Override
public int advance(int target) {
return nextDoc();
}
@Override
public int freq() {
return positions.size();
}
@Override
public int nextPosition() {
return positions.get(posUpto++);
}
@Override
public boolean hasPayload() {
return false;
}
@Override
public BytesRef getPayload() {
return null;
}
}
@Override
public TermEnum terms(Term term) {

View File

@ -232,46 +232,5 @@ public class MultiPassIndexSplitter {
public boolean isDeleted(int n) {
return dels.get(n);
}
@Override
public TermPositions termPositions() throws IOException {
return new FilterTermPositions(in.termPositions()) {
@Override
public boolean next() throws IOException {
boolean res;
while ((res = super.next())) {
if (!dels.get(doc())) {
break;
}
}
return res;
}
};
}
@Override
public TermDocs termDocs() throws IOException {
return new FilterTermDocs(in.termDocs()) {
@Override
public boolean next() throws IOException {
boolean res;
while ((res = super.next())) {
if (!dels.get(doc())) {
break;
}
}
return res;
}
};
}
@Override
public TermDocs termDocs(Term term) throws IOException {
TermDocs termDocs = termDocs();
termDocs.seek(term);
return termDocs;
}
}
}

View File

@ -37,6 +37,7 @@ public class RegexQuery extends MultiTermQuery implements RegexQueryCapable {
/** Constructs a query for terms matching <code>term</code>. */
public RegexQuery(Term term) {
super(term.field());
this.term = term;
}

View File

@ -27,6 +27,7 @@ import org.apache.lucene.util.BytesRef;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Comparator;
/** A <code>FilterIndexReader</code> contains another IndexReader, which it
* uses as its basic source of data, possibly transforming the data along the
@ -39,65 +40,219 @@ import java.util.Map;
*/
public class FilterIndexReader extends IndexReader {
/** Base class for filtering {@link TermDocs} implementations. */
public static class FilterTermDocs implements TermDocs {
protected TermDocs in;
/** Base class for filtering {@link Fields}
* implementations. */
public static class FilterFields extends Fields {
protected Fields in;
public FilterTermDocs(TermDocs in) { this.in = in; }
public void seek(Term term) throws IOException { in.seek(term); }
public void seek(TermEnum termEnum) throws IOException { in.seek(termEnum); }
public int doc() { return in.doc(); }
public int freq() { return in.freq(); }
public boolean next() throws IOException { return in.next(); }
public int read(int[] docs, int[] freqs) throws IOException {
return in.read(docs, freqs);
public FilterFields(Fields in) {
this.in = in;
}
@Override
public FieldsEnum iterator() throws IOException {
return in.iterator();
}
@Override
public Terms terms(String field) throws IOException {
return in.terms(field);
}
public boolean skipTo(int i) throws IOException { return in.skipTo(i); }
public void close() throws IOException { in.close(); }
}
/** Base class for filtering {@link TermPositions} implementations. */
public static class FilterTermPositions
extends FilterTermDocs implements TermPositions {
/** Base class for filtering {@link Terms}
* implementations. */
public static class FilterTerms extends Terms {
protected Terms in;
public FilterTermPositions(TermPositions in) { super(in); }
public FilterTerms(Terms in) {
this.in = in;
}
@Override
public TermsEnum iterator() throws IOException {
return in.iterator();
}
@Override
public Comparator<BytesRef> getComparator() throws IOException {
return in.getComparator();
}
@Override
public int docFreq(BytesRef text) throws IOException {
return in.docFreq(text);
}
@Override
public DocsEnum docs(Bits skipDocs, BytesRef text, DocsEnum reuse) throws IOException {
return in.docs(skipDocs, text, reuse);
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, BytesRef text, DocsAndPositionsEnum reuse) throws IOException {
return in.docsAndPositions(skipDocs, text, reuse);
}
@Override
public long getUniqueTermCount() throws IOException {
return in.getUniqueTermCount();
}
}
/** Base class for filtering {@link TermsEnum} implementations. */
public static class FilterFieldsEnum extends FieldsEnum {
protected FieldsEnum in;
public FilterFieldsEnum(FieldsEnum in) {
this.in = in;
}
@Override
public String next() throws IOException {
return in.next();
}
@Override
public TermsEnum terms() throws IOException {
return in.terms();
}
}
/** Base class for filtering {@link TermsEnum} implementations. */
public static class FilterTermsEnum extends TermsEnum {
protected TermsEnum in;
public FilterTermsEnum(TermsEnum in) { this.in = in; }
@Override
public SeekStatus seek(BytesRef text, boolean useCache) throws IOException {
return in.seek(text, useCache);
}
@Override
public SeekStatus seek(long ord) throws IOException {
return in.seek(ord);
}
@Override
public BytesRef next() throws IOException {
return in.next();
}
@Override
public BytesRef term() throws IOException {
return in.term();
}
@Override
public long ord() throws IOException {
return in.ord();
}
@Override
public int docFreq() {
return in.docFreq();
}
@Override
public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException {
return in.docs(skipDocs, reuse);
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException {
return in.docsAndPositions(skipDocs, reuse);
}
@Override
public Comparator<BytesRef> getComparator() throws IOException {
return in.getComparator();
}
}
/** Base class for filtering {@link DocsEnum} implementations. */
public static class FilterDocsEnum extends DocsEnum {
protected DocsEnum in;
public FilterDocsEnum(DocsEnum in) {
this.in = in;
}
@Override
public int docID() {
return in.docID();
}
@Override
public int freq() {
return in.freq();
}
@Override
public int nextDoc() throws IOException {
return in.nextDoc();
}
@Override
public int advance(int target) throws IOException {
return in.advance(target);
}
@Override
public BulkReadResult getBulkResult() {
return in.getBulkResult();
}
@Override
public int read() throws IOException {
return in.read();
}
}
/** Base class for filtering {@link DocsAndPositionsEnum} implementations. */
public static class FilterDocsAndPositionsEnum extends DocsAndPositionsEnum {
protected DocsAndPositionsEnum in;
public FilterDocsAndPositionsEnum(DocsAndPositionsEnum in) {
this.in = in;
}
@Override
public int docID() {
return in.docID();
}
@Override
public int freq() {
return in.freq();
}
@Override
public int nextDoc() throws IOException {
return in.nextDoc();
}
@Override
public int advance(int target) throws IOException {
return in.advance(target);
}
@Override
public int nextPosition() throws IOException {
return ((TermPositions) this.in).nextPosition();
}
public int getPayloadLength() throws IOException {
return ((TermPositions) this.in).getPayloadLength();
return in.nextPosition();
}
public byte[] getPayload(byte[] data, int offset) throws IOException {
return ((TermPositions) this.in).getPayload(data, offset);
@Override
public BytesRef getPayload() throws IOException {
return in.getPayload();
}
// TODO: Remove warning after API has been finalized
public boolean isPayloadAvailable() {
return ((TermPositions)this.in).isPayloadAvailable();
@Override
public boolean hasPayload() {
return in.hasPayload();
}
}
/** Base class for filtering {@link TermEnum} implementations. */
public static class FilterTermEnum extends TermEnum {
protected TermEnum in;
public FilterTermEnum(TermEnum in) { this.in = in; }
@Override
public boolean next() throws IOException { return in.next(); }
@Override
public Term term() { return in.term(); }
@Override
public int docFreq() { return in.docFreq(); }
@Override
public void close() throws IOException { in.close(); }
}
protected IndexReader in;
/**
@ -206,14 +361,16 @@ public class FilterIndexReader extends IndexReader {
in.setNorm(d, f, b);
}
// final to force subclass to impl flex APIs, instead
@Override
public TermEnum terms() throws IOException {
public final TermEnum terms() throws IOException {
ensureOpen();
return in.terms();
}
// final to force subclass to impl flex APIs, instead
@Override
public TermEnum terms(Term t) throws IOException {
public final TermEnum terms(Term t) throws IOException {
ensureOpen();
return in.terms(t);
}
@ -229,21 +386,24 @@ public class FilterIndexReader extends IndexReader {
ensureOpen();
return in.docFreq(field, t);
}
// final to force subclass to impl flex APIs, instead
@Override
public TermDocs termDocs() throws IOException {
public final TermDocs termDocs() throws IOException {
ensureOpen();
return in.termDocs();
}
// final to force subclass to impl flex APIs, instead
@Override
public TermDocs termDocs(Term term) throws IOException {
public final TermDocs termDocs(Term term) throws IOException {
ensureOpen();
return in.termDocs(term);
}
// final to force subclass to impl flex APIs, instead
@Override
public TermPositions termPositions() throws IOException {
public final TermPositions termPositions() throws IOException {
ensureOpen();
return in.termPositions();
}
@ -294,15 +454,9 @@ public class FilterIndexReader extends IndexReader {
return null;
}
/* Flex API wrappers. */
@Override
public Fields fields() throws IOException {
return new LegacyFields(this);
}
@Override
public Terms terms(String field) throws IOException {
return new LegacyTerms(this, field);
return MultiFields.getFields(in);
}
/** If the subclass of FilteredIndexReader modifies the

View File

@ -892,9 +892,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
* performance reasons, it's best to get all sub-readers
* using {@link ReaderUtil#gatherSubReaders} and iterate
* through them yourself. */
public Fields fields() throws IOException {
return new LegacyFields(this);
}
public abstract Fields fields() throws IOException;
/** Returns an enumeration of all terms starting at a given term. If
* the given term does not exist, the enumeration is positioned at the
@ -1211,6 +1209,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
// Only used by external subclasses of IndexReader; all
// internal classes should implement Bits more
// efficiently:
/*
private final class DeletedDocsBits implements Bits {
public boolean get(int docID) {
return isDeleted(docID);
@ -1221,6 +1220,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
}
private Bits deletedDocsBits;
*/
/** Returns the {@link Bits} representing deleted docs. A
* set bit indicates the doc ID has been deleted. This
@ -1228,12 +1228,7 @@ public abstract class IndexReader implements Cloneable,Closeable {
* docs.
*
* @lucene.experimental */
public Bits getDeletedDocs() throws IOException {
if (deletedDocsBits == null) {
deletedDocsBits = new DeletedDocsBits();
}
return deletedDocsBits;
}
public abstract Bits getDeletedDocs() throws IOException;
/**
* Expert: return the IndexCommit that this reader has

View File

@ -1,41 +0,0 @@
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;
/** Implements flex API (FieldsEnum/TermsEnum) on top of
* non-flex API. Used only for IndexReader impls outside
* Lucene's core. */
class LegacyFields extends Fields {
private final IndexReader r;
public LegacyFields(IndexReader r) throws IOException {
this.r = r;
}
@Override
public FieldsEnum iterator() throws IOException {
return new LegacyFieldsEnum(r);
}
@Override
public Terms terms(String field) throws IOException {
return new LegacyTerms(r, field);
}
}

View File

@ -1,332 +0,0 @@
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.Comparator;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
/** Implements flex API (FieldsEnum/TermsEnum) on top of
* pre-flex API. Used only for IndexReader impls outside
* Lucene's core.
*
* @deprecated Migrate the external reader to the flex API */
@Deprecated
class LegacyFieldsEnum extends FieldsEnum {
private final IndexReader r;
private TermEnum terms;
private String field;
private boolean init;
public LegacyFieldsEnum(IndexReader r) throws IOException {
this.r = r;
terms = r.terms();
init = true;
}
@Override
public String next() throws IOException {
if (field != null) {
terms.close();
// jump to end of the current field:
terms = r.terms(new Term(field, "\uFFFF"));
assert terms.term() == null || !terms.term().field.equals(field);
}
if (init) {
init = false;
if (!terms.next()) {
return null;
}
}
if (terms.term() != null) {
String newField = terms.term().field;
assert field == null || !newField.equals(field);
field = newField;
return field;
} else {
return null;
}
}
@Override
public TermsEnum terms() throws IOException {
return new LegacyTermsEnum(r, field);
}
static class LegacyTermsEnum extends TermsEnum {
private final IndexReader r;
private final String field;
private TermEnum terms;
private BytesRef current;
private final BytesRef tr = new BytesRef();
LegacyTermsEnum(IndexReader r, String field) throws IOException {
this.r = r;
this.field = field;
}
@Override
public Comparator<BytesRef> getComparator() {
// Pre-flex indexes always sorted in UTF16 order
return BytesRef.getUTF8SortedAsUTF16Comparator();
}
@Override
public SeekStatus seek(BytesRef text, boolean useCache) throws IOException {
if (terms != null) {
terms.close();
}
terms = r.terms(new Term(field, text.utf8ToString()));
final Term t = terms.term();
if (t == null) {
current = null;
return SeekStatus.END;
} else if (t.field() == field) {
tr.copy(t.text());
current = tr;
if (text.bytesEquals(tr)) {
return SeekStatus.FOUND;
} else {
return SeekStatus.NOT_FOUND;
}
} else {
return SeekStatus.END;
}
}
@Override
public SeekStatus seek(long ord) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public long ord() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public BytesRef next() throws IOException {
if (terms == null) {
// first next -- seek to start of field
terms = r.terms(new Term(field, ""));
final Term t = terms.term();
if (t == null || t.field != field) {
return null;
} else {
tr.copy(terms.term().text());
return current = tr;
}
} else if (terms.next()) {
if (terms.term().field == field) {
tr.copy(terms.term().text());
return current = tr;
} else {
return null;
}
} else {
return null;
}
}
@Override
public BytesRef term() {
return current;
}
@Override
public int docFreq() {
return terms.docFreq();
}
@Override
public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException {
if (reuse != null) {
return ((LegacyDocsEnum) reuse).reset(terms.term(), skipDocs);
} else {
return (new LegacyDocsEnum(r, field)).reset(terms.term(), skipDocs);
}
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException {
if (reuse != null) {
return ((LegacyDocsAndPositionsEnum) reuse).reset(terms.term(), skipDocs);
} else {
return (new LegacyDocsAndPositionsEnum(r, field)).reset(terms.term(), skipDocs);
}
}
public void close() throws IOException {
terms.close();
}
}
// Emulates flex on top of legacy API
private static class LegacyDocsEnum extends DocsEnum {
private final IndexReader r;
private final String field;
private final TermDocs td;
private Term term;
private int doc = -1;
LegacyDocsEnum(IndexReader r, String field) throws IOException {
this.r = r;
this.field = field;
td = r.termDocs();
}
public DocsEnum reset(Term term, Bits skipDocs) throws IOException {
this.term = term;
td.seek(term);
if (skipDocs != MultiFields.getDeletedDocs(r)) {
// An external reader's TermDocs/Positions will
// silently skip deleted docs, so, we can't allow
// arbitrary skipDocs here:
throw new IllegalStateException("external IndexReader requires skipDocs == MultiFields.getDeletedDocs()");
}
return this;
}
@Override
public int nextDoc() throws IOException {
if (td.next()) {
return doc = td.doc();
} else {
return doc = NO_MORE_DOCS;
}
}
@Override
public int advance(int target) throws IOException {
if (td.skipTo(target)) {
return doc = td.doc();
} else {
return doc = NO_MORE_DOCS;
}
}
@Override
public int freq() {
return td.freq();
}
@Override
public int docID() {
return doc;
}
}
// Emulates flex on top of legacy API
private static class LegacyDocsAndPositionsEnum extends DocsAndPositionsEnum {
private final IndexReader r;
private final String field;
private final TermPositions tp;
private Term term;
private int doc = -1;
LegacyDocsAndPositionsEnum(IndexReader r, String field) throws IOException {
this.r = r;
this.field = field;
tp = r.termPositions();
}
public DocsAndPositionsEnum reset(Term term, Bits skipDocs) throws IOException {
this.term = term;
tp.seek(term);
if (skipDocs != MultiFields.getDeletedDocs(r)) {
// An external reader's TermDocs/Positions will
// silently skip deleted docs, so, we can't allow
// arbitrary skipDocs here:
throw new IllegalStateException("external IndexReader requires skipDocs == MultiFields.getDeletedDocs() skipDocs=" + skipDocs + " MultiFields.getDeletedDocs=" + MultiFields.getDeletedDocs(r) + " r=" + r);
}
return this;
}
@Override
public int nextDoc() throws IOException {
if (tp.next()) {
return doc = tp.doc();
} else {
return doc = NO_MORE_DOCS;
}
}
@Override
public int advance(int target) throws IOException {
if (tp.skipTo(target)) {
return doc = tp.doc();
} else {
return doc = NO_MORE_DOCS;
}
}
@Override
public int freq() {
return tp.freq();
}
@Override
public int docID() {
return doc;
}
// NOTE: we don't override bulk-read (docs & freqs) API
// -- leave it to base class, because TermPositions
// can't do bulk read
@Override
public int nextPosition() throws IOException {
return tp.nextPosition();
}
private BytesRef payload;
@Override
public BytesRef getPayload() throws IOException {
final int len = tp.getPayloadLength();
if (payload == null) {
payload = new BytesRef();
payload.bytes = new byte[len];
} else {
if (payload.bytes.length < len) {
payload.grow(len);
}
}
payload.bytes = tp.getPayload(payload.bytes, 0);
payload.length = len;
return payload;
}
@Override
public boolean hasPayload() {
return tp.isPayloadAvailable();
}
}
}

View File

@ -1,52 +0,0 @@
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.Comparator;
import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.BytesRef;
/** Implements flex API (FieldsEnum/TermsEnum) on top of
* pre-flex API. Used only for IndexReader impls outside
* Lucene's core. */
class LegacyTerms extends Terms {
private final IndexReader r;
private final String field;
LegacyTerms(IndexReader r, String field) {
this.r = r;
this.field = StringHelper.intern(field);
}
@Override
public TermsEnum iterator() throws IOException {
return new LegacyFieldsEnum.LegacyTermsEnum(r, field);
}
@Override
public Comparator<BytesRef> getComparator() {
// Pre-flex indexes always sorted in UTF16 order
return BytesRef.getUTF8SortedAsUTF16Comparator();
}
}

View File

@ -76,10 +76,7 @@ public class FlexTestUtil {
// Then on each individual sub reader
IndexReader[] subReaders = r.getSequentialSubReaders();
IndexReader[] forcedSubReaders = new IndexReader[subReaders.length];
for(int i=0;i<subReaders.length;i++) {
forcedSubReaders[i] = new ForcedExternalReader(subReaders[i]);
verifyFlexVsPreFlexSingle(rand, forcedSubReaders[i]);
verifyFlexVsPreFlexSingle(rand, subReaders[i]);
}
@ -87,15 +84,6 @@ public class FlexTestUtil {
IndexReader m = new MultiReader(subReaders, false);
verifyFlexVsPreFlexSingle(rand, m);
m.close();
// Then on a forced-external reader (forced flex to
// emulate API on pre-flex API, which in turn is
// emulating pre-flex on flex -- twisted, but, better
// work):
verifyFlexVsPreFlexSingle(rand, new ForcedExternalReader(r));
m = new MultiReader(forcedSubReaders, false);
verifyFlexVsPreFlexSingle(rand, m);
m.close();
}
private static void verifyFlexVsPreFlexSingle(Random rand, IndexReader r) throws Exception {
@ -538,115 +526,6 @@ public class FlexTestUtil {
}
}
// Delegates to a "normal" IndexReader, making it look
// "external", to force testing of the "flex API on
// external reader" layer. DO NOT OVERRIDE
// getSequentialSubReaders!!
public final static class ForcedExternalReader extends IndexReader {
private final IndexReader r;
public ForcedExternalReader(IndexReader r) {
this.r = r;
}
public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException {
return r.getTermFreqVectors(docNumber);
}
public TermFreqVector getTermFreqVector(int docNumber, String field) throws IOException {
return r.getTermFreqVector(docNumber, field);
}
public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) throws IOException {
r.getTermFreqVector(docNumber, field, mapper);
}
public void getTermFreqVector(int docNumber, TermVectorMapper mapper) throws IOException {
r.getTermFreqVector(docNumber, mapper);
}
public Bits getDeletedDocs() throws IOException {
return MultiFields.getDeletedDocs(r);
}
public int numDocs() {
return r.numDocs();
}
public int maxDoc() {
return r.maxDoc();
}
public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
return r.document(n, fieldSelector);
}
public boolean isDeleted(int n) {
return r.isDeleted(n);
}
public boolean hasDeletions() {
return r.hasDeletions();
}
public byte[] norms(String field) throws IOException {
return r.norms(field);
}
public String toString() {
return "ForcedExternalReader(" + r + ")";
}
public void norms(String field, byte[] bytes, int offset)
throws IOException {
r.norms(field, bytes, offset);
}
protected void doSetNorm(int doc, String field, byte value)
throws CorruptIndexException, IOException {
r.doSetNorm(doc, field, value);
}
public TermEnum terms() throws IOException {
return r.terms();
}
public TermEnum terms(Term t) throws IOException {
return r.terms(t);
}
public int docFreq(Term t) throws IOException {
return r.docFreq(t);
}
public TermDocs termDocs() throws IOException {
return r.termDocs();
}
public TermPositions termPositions() throws IOException {
return r.termPositions();
}
public void doDelete(int docID) throws IOException {
r.doDelete(docID);
}
public void doUndeleteAll() throws IOException {
r.doUndeleteAll();
}
protected void doCommit(Map<String, String> commitUserData) throws IOException {
r.doCommit(commitUserData);
}
protected void doClose() throws IOException {
r.doClose();
}
public Collection<String> getFieldNames(FieldOption fldOption) {
return r.getFieldNames(fldOption);
}
}
public static void main(String[] args) throws Exception {
//Directory dir = FSDirectory.open(new File("/x/lucene/wiki.5M/index"));
Directory dir = FSDirectory.open(new File("/x/lucene/flex.wiki.1M/index"));

View File

@ -27,6 +27,8 @@ import org.apache.lucene.store.MockRAMDirectory;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Bits;
import java.io.IOException;
@ -34,37 +36,76 @@ public class TestFilterIndexReader extends LuceneTestCase {
private static class TestReader extends FilterIndexReader {
/** Filter that only permits terms containing 'e'.*/
private static class TestTermEnum extends FilterTermEnum {
public TestTermEnum(TermEnum termEnum) {
super(termEnum);
/** Filter that only permits terms containing 'e'.*/
private static class TestFields extends FilterFields {
TestFields(Fields in) {
super(in);
}
public FieldsEnum iterator() throws IOException {
return new TestFieldsEnum(super.iterator());
}
public Terms terms(String field) throws IOException {
return new TestTerms(super.terms(field));
}
}
private static class TestTerms extends FilterTerms {
TestTerms(Terms in) {
super(in);
}
public TermsEnum iterator() throws IOException {
return new TestTermsEnum(super.iterator());
}
}
private static class TestFieldsEnum extends FilterFieldsEnum {
TestFieldsEnum(FieldsEnum in) {
super(in);
}
public TermsEnum terms() throws IOException {
return new TestTermsEnum(super.terms());
}
}
private static class TestTermsEnum extends FilterTermsEnum {
public TestTermsEnum(TermsEnum in) {
super(in);
}
/** Scan for terms containing the letter 'e'.*/
@Override
public boolean next() throws IOException {
while (in.next()) {
if (in.term().text().indexOf('e') != -1)
return true;
public BytesRef next() throws IOException {
BytesRef text;
while ((text = in.next()) != null) {
if (text.utf8ToString().indexOf('e') != -1)
return text;
}
return false;
return null;
}
@Override
public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException {
return new TestPositions(super.docsAndPositions(skipDocs, reuse == null ? null : ((FilterDocsAndPositionsEnum) reuse).in));
}
}
/** Filter that only returns odd numbered documents. */
private static class TestTermPositions extends FilterTermPositions {
public TestTermPositions(TermPositions in) {
private static class TestPositions extends FilterDocsAndPositionsEnum {
public TestPositions(DocsAndPositionsEnum in) {
super(in);
}
/** Scan for odd numbered documents. */
@Override
public boolean next() throws IOException {
while (in.next()) {
if ((in.doc() % 2) == 1)
return true;
public int nextDoc() throws IOException {
int doc;
while ((doc = in.nextDoc()) != NO_MORE_DOCS) {
if ((doc % 2) == 1)
return doc;
}
return false;
return NO_MORE_DOCS;
}
}
@ -72,16 +113,9 @@ public class TestFilterIndexReader extends LuceneTestCase {
super(reader);
}
/** Filter terms with TestTermEnum. */
@Override
public TermEnum terms() throws IOException {
return new TestTermEnum(in.terms());
}
/** Filter positions with TestTermPositions. */
@Override
public TermPositions termPositions() throws IOException {
return new TestTermPositions(in.termPositions());
public Fields fields() throws IOException {
return new TestFields(super.fields());
}
}

View File

@ -1,82 +0,0 @@
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.*;
import java.util.*;
import org.apache.lucene.store.*;
import org.apache.lucene.search.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.document.*;
import org.apache.lucene.util.*;
public class TestFlexExternalReader extends LuceneTestCase {
public void testExternalReader() throws Exception {
Directory d = new MockRAMDirectory();
final int DOC_COUNT = 177;
IndexWriter w = new IndexWriter(d, new MockAnalyzer(),
IndexWriter.MaxFieldLength.UNLIMITED);
w.setMaxBufferedDocs(7);
Document doc = new Document();
doc.add(new Field("field1", "this is field1", Field.Store.NO, Field.Index.ANALYZED));
doc.add(new Field("field2", "this is field2", Field.Store.NO, Field.Index.ANALYZED));
doc.add(new Field("field3", "aaa", Field.Store.NO, Field.Index.ANALYZED));
doc.add(new Field("field4", "bbb", Field.Store.NO, Field.Index.ANALYZED));
for(int i=0;i<DOC_COUNT;i++) {
w.addDocument(doc);
}
IndexReader r = new FlexTestUtil.ForcedExternalReader(w.getReader());
BytesRef field1Term = new BytesRef("field1");
BytesRef field2Term = new BytesRef("field2");
assertEquals(DOC_COUNT, r.maxDoc());
assertEquals(DOC_COUNT, r.numDocs());
assertEquals(DOC_COUNT, r.docFreq(new Term("field1", "field1")));
assertEquals(DOC_COUNT, r.docFreq("field1", field1Term));
Fields fields = r.fields();
Terms terms = fields.terms("field1");
TermsEnum termsEnum = terms.iterator();
assertEquals(TermsEnum.SeekStatus.FOUND, termsEnum.seek(field1Term));
assertEquals(TermsEnum.SeekStatus.NOT_FOUND, termsEnum.seek(field2Term));
assertTrue(new BytesRef("is").bytesEquals(termsEnum.term()));
terms = fields.terms("field2");
termsEnum = terms.iterator();
assertEquals(TermsEnum.SeekStatus.NOT_FOUND, termsEnum.seek(field1Term));
assertTrue(termsEnum.term().bytesEquals(field2Term));
assertEquals(TermsEnum.SeekStatus.FOUND, termsEnum.seek(field2Term));
termsEnum = fields.terms("field3").iterator();
assertEquals(TermsEnum.SeekStatus.END, termsEnum.seek(new BytesRef("bbb")));
assertEquals(TermsEnum.SeekStatus.FOUND, termsEnum.seek(new BytesRef("aaa")));
assertNull(termsEnum.next());
r.close();
w.close();
d.close();
}
}

View File

@ -299,21 +299,11 @@ public class SolrIndexReader extends FilterIndexReader {
in.setNorm(d, f, b);
}
@Override
public TermEnum terms() throws IOException {
return in.terms();
}
@Override
public Fields fields() throws IOException {
return in.fields();
}
@Override
public TermEnum terms(Term t) throws IOException {
return in.terms(t);
}
@Override
public int docFreq(Term t) throws IOException {
ensureOpen();
@ -325,18 +315,6 @@ public class SolrIndexReader extends FilterIndexReader {
return in.docFreq(field, t);
}
@Override
public TermDocs termDocs() throws IOException {
ensureOpen();
return in.termDocs();
}
@Override
public TermDocs termDocs(Term term) throws IOException {
ensureOpen();
return in.termDocs(term);
}
@Override
public Terms terms(String field) throws IOException {
return in.terms(field);
@ -352,12 +330,6 @@ public class SolrIndexReader extends FilterIndexReader {
return in.termPositionsEnum(skipDocs, field, term);
}
@Override
public TermPositions termPositions() throws IOException {
ensureOpen();
return in.termPositions();
}
@Override
protected void doDelete(int n) throws CorruptIndexException, IOException { in.deleteDocument(n); }