Index: lucene/core/src/java/org/apache/lucene/index/AtomicReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/AtomicReader.java (revision 1452053) +++ lucene/core/src/java/org/apache/lucene/index/AtomicReader.java (working copy) @@ -60,13 +60,6 @@ return readerContext; } - /** - * Returns {@link Fields} for this reader. - * This method may return null if the reader has no - * postings. - */ - public abstract Fields fields() throws IOException; - @Override public final int docFreq(Term term) throws IOException { final Fields fields = fields(); @@ -108,55 +101,6 @@ } } - /** This may return null if the field does not exist.*/ - public final Terms terms(String field) throws IOException { - final Fields fields = fields(); - if (fields == null) { - return null; - } - return fields.terms(field); - } - - /** Returns {@link DocsEnum} for the specified term. - * This will return null if either the field or - * term does not exist. - * @see TermsEnum#docs(Bits, DocsEnum) */ - public final DocsEnum termDocsEnum(Term term) throws IOException { - assert term.field() != null; - assert term.bytes() != null; - final Fields fields = fields(); - if (fields != null) { - final Terms terms = fields.terms(term.field()); - if (terms != null) { - final TermsEnum termsEnum = terms.iterator(null); - if (termsEnum.seekExact(term.bytes(), true)) { - 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. - * @see TermsEnum#docsAndPositions(Bits, DocsAndPositionsEnum) */ - public final DocsAndPositionsEnum termPositionsEnum(Term term) throws IOException { - assert term.field() != null; - assert term.bytes() != null; - final Fields fields = fields(); - if (fields != null) { - final Terms terms = fields.terms(term.field()); - if (terms != null) { - final TermsEnum termsEnum = terms.iterator(null); - if (termsEnum.seekExact(term.bytes(), true)) { - return termsEnum.docsAndPositions(getLiveDocs(), null); - } - } - } - return null; - } - /** Returns {@link NumericDocValues} for this field, or * null if no {@link NumericDocValues} were indexed for * this field. The returned instance should only be @@ -193,16 +137,4 @@ * @lucene.experimental */ public abstract FieldInfos getFieldInfos(); - - /** Returns the {@link Bits} representing live (not - * deleted) docs. A set bit indicates the doc ID has not - * been deleted. If this method returns null it means - * there are no deleted documents (all documents are - * live). - * - * The returned instance has been safely published for - * use by multiple threads without additional - * synchronization. - */ - public abstract Bits getLiveDocs(); } Index: lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java (revision 1452053) +++ lucene/core/src/java/org/apache/lucene/index/SlowCompositeReaderWrapper.java (working copy) @@ -48,8 +48,6 @@ public final class SlowCompositeReaderWrapper extends AtomicReader { private final CompositeReader in; - private final Fields fields; - private final Bits liveDocs; /** This method is sugar for getting an {@link AtomicReader} from * an {@link IndexReader} of any kind. If the reader is already atomic, @@ -69,8 +67,6 @@ public SlowCompositeReaderWrapper(CompositeReader reader) throws IOException { super(); in = reader; - fields = MultiFields.getFields(in); - liveDocs = MultiFields.getLiveDocs(in); in.registerParentReader(this); } @@ -79,10 +75,10 @@ return "SlowCompositeReaderWrapper(" + in + ")"; } - @Override - public Fields fields() { + @Override + public Fields fields() throws IOException { ensureOpen(); - return fields; + return MultiFields.getFields(in); } @Override @@ -203,15 +199,15 @@ } @Override - public void document(int docID, StoredFieldVisitor visitor) throws IOException { + public Bits getLiveDocs() { ensureOpen(); - in.document(docID, visitor); + return MultiFields.getLiveDocs(in); } @Override - public Bits getLiveDocs() { + public void document(int docID, StoredFieldVisitor visitor) throws IOException { ensureOpen(); - return liveDocs; + in.document(docID, visitor); } @Override @@ -223,7 +219,10 @@ @Override public boolean hasDeletions() { ensureOpen(); - return liveDocs != null; + int numDocs = in.numDocs(); + int maxDoc = in.maxDoc(); + assert numDocs <= maxDoc; + return numDocs < maxDoc; } @Override Index: lucene/core/src/java/org/apache/lucene/index/IndexReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/IndexReader.java (revision 1452053) +++ lucene/core/src/java/org/apache/lucene/index/IndexReader.java (working copy) @@ -446,4 +446,86 @@ * @see TermsEnum#totalTermFreq() */ public abstract long totalTermFreq(Term term) throws IOException; + + /** Returns {@link Fields} for this reader. + * This method may return null if the reader has no + * postings. + * + *
NOTE: if this reader has multiple {@link + * leaves}, it's faster to work directly with each + * sub-reader instead. */ + public Fields fields() throws IOException { + return MultiFields.getFields(this); + } + + /** Returns {@link Terms} for a given field, or null if + * the field does not exist. + * + *
NOTE: if this reader has multiple {@link + * leaves}, it's faster to work directly with each + * sub-reader instead. */ + public final Terms terms(String field) throws IOException { + final Fields fields = fields(); + if (fields == null) { + return null; + } + return fields.terms(field); + } + + /** Returns {@link DocsEnum} for the specified term. + * This will return null if either the field or + * term does not exist. + * @see TermsEnum#docs(Bits, DocsEnum) */ + public final DocsEnum termDocsEnum(Term term) throws IOException { + assert term.field() != null; + assert term.bytes() != null; + final Fields fields = fields(); + if (fields != null) { + final Terms terms = fields.terms(term.field()); + if (terms != null) { + final TermsEnum termsEnum = terms.iterator(null); + if (termsEnum.seekExact(term.bytes(), true)) { + 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. + * @see TermsEnum#docsAndPositions(Bits, DocsAndPositionsEnum) */ + public final DocsAndPositionsEnum termPositionsEnum(Term term) throws IOException { + assert term.field() != null; + assert term.bytes() != null; + final Fields fields = fields(); + if (fields != null) { + final Terms terms = fields.terms(term.field()); + if (terms != null) { + final TermsEnum termsEnum = terms.iterator(null); + if (termsEnum.seekExact(term.bytes(), true)) { + return termsEnum.docsAndPositions(getLiveDocs(), null); + } + } + } + return null; + } + + /** Returns the {@link Bits} representing live (not + * deleted) docs. A set bit indicates the doc ID has not + * been deleted. If this method returns null it means + * there are no deleted documents (all documents are + * live). + * + *
The returned instance has been safely published for + * use by multiple threads without additional + * synchronization. + * + *
NOTE: if this reader has multiple {@link + * leaves}, it's faster to work directly with each + * sub-reader instead. */ + public Bits getLiveDocs() { + return MultiFields.getLiveDocs(this); + } }