Index: lucene/CHANGES.txt =================================================================== --- lucene/CHANGES.txt (revision 1243048) +++ lucene/CHANGES.txt (working copy) @@ -228,7 +228,7 @@ Similarity to use an external byte[] or one of the new DocValues fields (LUCENE-3108). Alternatively, to dynamically change norms (boost *and* length norm) at query time, wrap your AtomicReader using - FilterIndexReader, overriding FilterIndexReader.norms(). To persist the + FilterAtomicReader, overriding FilterAtomicReader.norms(). To persist the changes on disk, copy the FilteredIndexReader to a new index using IndexWriter.addIndexes(). (Uwe Schindler, Robert Muir) @@ -240,10 +240,11 @@ FieldInfo.IndexOption: DOCS_AND_POSITIONS_AND_OFFSETS. (Robert Muir, Mike McCandless) -* LUCENE-2858: FilterIndexReader now extends AtomicReader. If you want to - filter composite readers like DirectoryReader or MultiReader, filter - their atomic leaves and build a new CompositeReader (e.g. MultiReader) - around them. (Uwe Schindler, Robert Muir) +* LUCENE-2858, LUCENE-3770: FilterIndexReader was renamed to + FilterAtomicReader and now extends AtomicReader. If you want to filter + composite readers like DirectoryReader or MultiReader, filter their + atomic leaves and build a new CompositeReader (e.g. MultiReader) around + them. (Uwe Schindler, Robert Muir) * LUCENE-3736: ParallelReader was split into ParallelAtomicReader and ParallelCompositeReader. Lucene 3.x's ParallelReader is now Index: lucene/contrib/misc/src/java/org/apache/lucene/index/MultiPassIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/index/MultiPassIndexSplitter.java (revision 1243048) +++ lucene/contrib/misc/src/java/org/apache/lucene/index/MultiPassIndexSplitter.java (working copy) @@ -209,7 +209,7 @@ // as we pass the subreaders directly to IW.addIndexes(). } - private static final class FakeDeleteAtomicIndexReader extends FilterIndexReader { + private static final class FakeDeleteAtomicIndexReader extends FilterAtomicReader { FixedBitSet liveDocs; public FakeDeleteAtomicIndexReader(AtomicReader reader) { Index: lucene/contrib/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java =================================================================== --- lucene/contrib/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java (revision 1243048) +++ lucene/contrib/misc/src/java/org/apache/lucene/index/PKIndexSplitter.java (working copy) @@ -117,7 +117,7 @@ } } - private static class DocumentFilteredAtomicIndexReader extends FilterIndexReader { + private static class DocumentFilteredAtomicIndexReader extends FilterAtomicReader { final Bits liveDocs; final int numDocs; Index: lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java (working copy) @@ -0,0 +1,383 @@ +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.util.Bits; +import org.apache.lucene.util.BytesRef; + +import java.io.IOException; +import java.util.Comparator; + +/** A FilterAtomicReader contains another AtomicReader, which it + * uses as its basic source of data, possibly transforming the data along the + * way or providing additional functionality. The class + * FilterIndexReader itself simply implements all abstract methods + * of IndexReader with versions that pass all requests to the + * contained index reader. Subclasses of FilterAtomicReader may + * further override some of these methods and may also provide additional + * methods and fields. + */ +public class FilterAtomicReader extends AtomicReader { + + /** Base class for filtering {@link Fields} + * implementations. */ + public static class FilterFields extends Fields { + protected Fields in; + + 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); + } + + @Override + public int getUniqueFieldCount() throws IOException { + return in.getUniqueFieldCount(); + } + } + + /** Base class for filtering {@link Terms} + * implementations. */ + public static class FilterTerms extends Terms { + protected Terms in; + + public FilterTerms(Terms in) { + this.in = in; + } + + @Override + public TermsEnum iterator(TermsEnum reuse) throws IOException { + return in.iterator(reuse); + } + + @Override + public Comparator getComparator() throws IOException { + return in.getComparator(); + } + + @Override + public long getUniqueTermCount() throws IOException { + return in.getUniqueTermCount(); + } + + @Override + public long getSumTotalTermFreq() throws IOException { + return in.getSumTotalTermFreq(); + } + + @Override + public long getSumDocFreq() throws IOException { + return in.getSumDocFreq(); + } + + @Override + public int getDocCount() throws IOException { + return in.getDocCount(); + } + } + + /** 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 Terms 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 boolean seekExact(BytesRef text, boolean useCache) throws IOException { + return in.seekExact(text, useCache); + } + + @Override + public SeekStatus seekCeil(BytesRef text, boolean useCache) throws IOException { + return in.seekCeil(text, useCache); + } + + @Override + public void seekExact(long ord) throws IOException { + in.seekExact(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() throws IOException { + return in.docFreq(); + } + + @Override + public long totalTermFreq() throws IOException { + return in.totalTermFreq(); + } + + @Override + public DocsEnum docs(Bits liveDocs, DocsEnum reuse, boolean needsFreqs) throws IOException { + return in.docs(liveDocs, reuse, needsFreqs); + } + + @Override + public DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, boolean needsOffsets) throws IOException { + return in.docsAndPositions(liveDocs, reuse, needsOffsets); + } + + @Override + public Comparator getComparator() throws IOException { + return in.getComparator(); + } + + @Override + public void seekExact(BytesRef term, TermState state) throws IOException { + in.seekExact(term, state); + } + + @Override + public TermState termState() throws IOException { + return in.termState(); + } + } + + /** 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); + } + } + + /** 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 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 boolean hasPayload() { + return in.hasPayload(); + } + } + + protected AtomicReader in; + + /** + *

Construct a FilterIndexReader based on the specified base reader. + *

Note that base reader is closed if this FilterIndexReader is closed.

+ * @param in specified base reader. + */ + public FilterAtomicReader(AtomicReader in) { + super(); + this.in = in; + } + + @Override + public Bits getLiveDocs() { + ensureOpen(); + return in.getLiveDocs(); + } + + @Override + public FieldInfos getFieldInfos() { + return in.getFieldInfos(); + } + + @Override + public Fields getTermVectors(int docID) + throws IOException { + ensureOpen(); + return in.getTermVectors(docID); + } + + @Override + public int numDocs() { + // Don't call ensureOpen() here (it could affect performance) + return in.numDocs(); + } + + @Override + public int maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return in.maxDoc(); + } + + @Override + public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { + ensureOpen(); + in.document(docID, visitor); + } + + @Override + public boolean hasDeletions() { + ensureOpen(); + return in.hasDeletions(); + } + + @Override + public boolean hasNorms(String field) throws IOException { + ensureOpen(); + return in.hasNorms(field); + } + + @Override + protected void doClose() throws IOException { + in.close(); + } + + @Override + public Fields fields() throws IOException { + ensureOpen(); + return in.fields(); + } + + /** {@inheritDoc} + *

If the subclass of FilteredIndexReader modifies the + * contents (but not liveDocs) of the index, you must override this + * method to provide a different key. */ + @Override + public Object getCoreCacheKey() { + return in.getCoreCacheKey(); + } + + /** {@inheritDoc} + *

If the subclass of FilteredIndexReader modifies the + * liveDocs, you must override this + * method to provide a different key. */ + @Override + public Object getCombinedCoreAndDeletesKey() { + return in.getCombinedCoreAndDeletesKey(); + } + + @Override + public String toString() { + final StringBuilder buffer = new StringBuilder("FilterIndexReader("); + buffer.append(in); + buffer.append(')'); + return buffer.toString(); + } + + @Override + public DocValues docValues(String field) throws IOException { + ensureOpen(); + return in.docValues(field); + } + + @Override + public DocValues normValues(String field) throws IOException { + ensureOpen(); + return in.normValues(field); + } +} Index: lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java (revision 1243048) +++ lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java (working copy) Property changes on: lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java ___________________________________________________________________ Added: cvs2svn:cvs-rev ## -0,0 +1 ## +1.15 Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision Added: svn:eol-style ## -0,0 +1 ## +native Index: lucene/core/src/java/org/apache/lucene/index/FilterIndexReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/FilterIndexReader.java (revision 1243048) +++ lucene/core/src/java/org/apache/lucene/index/FilterIndexReader.java (working copy) @@ -1,383 +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 org.apache.lucene.util.Bits; -import org.apache.lucene.util.BytesRef; - -import java.io.IOException; -import java.util.Comparator; - -/** A FilterIndexReader contains another IndexReader, which it - * uses as its basic source of data, possibly transforming the data along the - * way or providing additional functionality. The class - * FilterIndexReader itself simply implements all abstract methods - * of IndexReader with versions that pass all requests to the - * contained index reader. Subclasses of FilterIndexReader may - * further override some of these methods and may also provide additional - * methods and fields. - */ -public class FilterIndexReader extends AtomicReader { - - /** Base class for filtering {@link Fields} - * implementations. */ - public static class FilterFields extends Fields { - protected Fields in; - - 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); - } - - @Override - public int getUniqueFieldCount() throws IOException { - return in.getUniqueFieldCount(); - } - } - - /** Base class for filtering {@link Terms} - * implementations. */ - public static class FilterTerms extends Terms { - protected Terms in; - - public FilterTerms(Terms in) { - this.in = in; - } - - @Override - public TermsEnum iterator(TermsEnum reuse) throws IOException { - return in.iterator(reuse); - } - - @Override - public Comparator getComparator() throws IOException { - return in.getComparator(); - } - - @Override - public long getUniqueTermCount() throws IOException { - return in.getUniqueTermCount(); - } - - @Override - public long getSumTotalTermFreq() throws IOException { - return in.getSumTotalTermFreq(); - } - - @Override - public long getSumDocFreq() throws IOException { - return in.getSumDocFreq(); - } - - @Override - public int getDocCount() throws IOException { - return in.getDocCount(); - } - } - - /** 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 Terms 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 boolean seekExact(BytesRef text, boolean useCache) throws IOException { - return in.seekExact(text, useCache); - } - - @Override - public SeekStatus seekCeil(BytesRef text, boolean useCache) throws IOException { - return in.seekCeil(text, useCache); - } - - @Override - public void seekExact(long ord) throws IOException { - in.seekExact(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() throws IOException { - return in.docFreq(); - } - - @Override - public long totalTermFreq() throws IOException { - return in.totalTermFreq(); - } - - @Override - public DocsEnum docs(Bits liveDocs, DocsEnum reuse, boolean needsFreqs) throws IOException { - return in.docs(liveDocs, reuse, needsFreqs); - } - - @Override - public DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, boolean needsOffsets) throws IOException { - return in.docsAndPositions(liveDocs, reuse, needsOffsets); - } - - @Override - public Comparator getComparator() throws IOException { - return in.getComparator(); - } - - @Override - public void seekExact(BytesRef term, TermState state) throws IOException { - in.seekExact(term, state); - } - - @Override - public TermState termState() throws IOException { - return in.termState(); - } - } - - /** 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); - } - } - - /** 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 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 boolean hasPayload() { - return in.hasPayload(); - } - } - - protected AtomicReader in; - - /** - *

Construct a FilterIndexReader based on the specified base reader. - *

Note that base reader is closed if this FilterIndexReader is closed.

- * @param in specified base reader. - */ - public FilterIndexReader(AtomicReader in) { - super(); - this.in = in; - } - - @Override - public Bits getLiveDocs() { - ensureOpen(); - return in.getLiveDocs(); - } - - @Override - public FieldInfos getFieldInfos() { - return in.getFieldInfos(); - } - - @Override - public Fields getTermVectors(int docID) - throws IOException { - ensureOpen(); - return in.getTermVectors(docID); - } - - @Override - public int numDocs() { - // Don't call ensureOpen() here (it could affect performance) - return in.numDocs(); - } - - @Override - public int maxDoc() { - // Don't call ensureOpen() here (it could affect performance) - return in.maxDoc(); - } - - @Override - public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { - ensureOpen(); - in.document(docID, visitor); - } - - @Override - public boolean hasDeletions() { - ensureOpen(); - return in.hasDeletions(); - } - - @Override - public boolean hasNorms(String field) throws IOException { - ensureOpen(); - return in.hasNorms(field); - } - - @Override - protected void doClose() throws IOException { - in.close(); - } - - @Override - public Fields fields() throws IOException { - ensureOpen(); - return in.fields(); - } - - /** {@inheritDoc} - *

If the subclass of FilteredIndexReader modifies the - * contents (but not liveDocs) of the index, you must override this - * method to provide a different key. */ - @Override - public Object getCoreCacheKey() { - return in.getCoreCacheKey(); - } - - /** {@inheritDoc} - *

If the subclass of FilteredIndexReader modifies the - * liveDocs, you must override this - * method to provide a different key. */ - @Override - public Object getCombinedCoreAndDeletesKey() { - return in.getCombinedCoreAndDeletesKey(); - } - - @Override - public String toString() { - final StringBuilder buffer = new StringBuilder("FilterIndexReader("); - buffer.append(in); - buffer.append(')'); - return buffer.toString(); - } - - @Override - public DocValues docValues(String field) throws IOException { - ensureOpen(); - return in.docValues(field); - } - - @Override - public DocValues normValues(String field) throws IOException { - ensureOpen(); - return in.normValues(field); - } -} Index: lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java (revision 0) +++ lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java (working copy) @@ -0,0 +1,197 @@ +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.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashSet; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.TextField; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.MockDirectoryWrapper; +import org.apache.lucene.util.Bits; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util.ReaderUtil; + +public class TestFilterAtomicReader extends LuceneTestCase { + + private static class TestReader extends FilterAtomicReader { + + /** Filter that only permits terms containing 'e'.*/ + private static class TestFields extends FilterFields { + TestFields(Fields in) { + super(in); + } + @Override + public FieldsEnum iterator() throws IOException { + return new TestFieldsEnum(super.iterator()); + } + @Override + public Terms terms(String field) throws IOException { + return new TestTerms(super.terms(field)); + } + } + + private static class TestTerms extends FilterTerms { + TestTerms(Terms in) { + super(in); + } + + @Override + public TermsEnum iterator(TermsEnum reuse) throws IOException { + return new TestTermsEnum(super.iterator(reuse)); + } + } + + private static class TestFieldsEnum extends FilterFieldsEnum { + TestFieldsEnum(FieldsEnum in) { + super(in); + } + + @Override + public Terms terms() throws IOException { + return new TestTerms(super.terms()); + } + } + + private static class TestTermsEnum extends FilterTermsEnum { + public TestTermsEnum(TermsEnum in) { + super(in); + } + + /** Scan for terms containing the letter 'e'.*/ + @Override + public BytesRef next() throws IOException { + BytesRef text; + while ((text = in.next()) != null) { + if (text.utf8ToString().indexOf('e') != -1) + return text; + } + return null; + } + + @Override + public DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, boolean needsOffsets) throws IOException { + return new TestPositions(super.docsAndPositions(liveDocs, reuse == null ? null : ((FilterDocsAndPositionsEnum) reuse).in, needsOffsets)); + } + } + + /** Filter that only returns odd numbered documents. */ + private static class TestPositions extends FilterDocsAndPositionsEnum { + public TestPositions(DocsAndPositionsEnum in) { + super(in); + } + + /** Scan for odd numbered documents. */ + @Override + public int nextDoc() throws IOException { + int doc; + while ((doc = in.nextDoc()) != NO_MORE_DOCS) { + if ((doc % 2) == 1) + return doc; + } + return NO_MORE_DOCS; + } + } + + public TestReader(IndexReader reader) throws IOException { + super(SlowCompositeReaderWrapper.wrap(reader)); + } + + @Override + public Fields fields() throws IOException { + return new TestFields(super.fields()); + } + } + + /** + * Tests the IndexReader.getFieldNames implementation + * @throws Exception on error + */ + public void testFilterIndexReader() throws Exception { + Directory directory = newDirectory(); + + IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); + + Document d1 = new Document(); + d1.add(newField("default","one two", TextField.TYPE_STORED)); + writer.addDocument(d1); + + Document d2 = new Document(); + d2.add(newField("default","one three", TextField.TYPE_STORED)); + writer.addDocument(d2); + + Document d3 = new Document(); + d3.add(newField("default","two four", TextField.TYPE_STORED)); + writer.addDocument(d3); + + writer.close(); + + Directory target = newDirectory(); + + // We mess with the postings so this can fail: + ((MockDirectoryWrapper) target).setCrossCheckTermVectorsOnClose(false); + + writer = new IndexWriter(target, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); + IndexReader reader = new TestReader(IndexReader.open(directory)); + writer.addIndexes(reader); + writer.close(); + reader.close(); + reader = IndexReader.open(target); + + TermsEnum terms = MultiFields.getTerms(reader, "default").iterator(null); + while (terms.next() != null) { + assertTrue(terms.term().utf8ToString().indexOf('e') != -1); + } + + assertEquals(TermsEnum.SeekStatus.FOUND, terms.seekCeil(new BytesRef("one"))); + + DocsAndPositionsEnum positions = terms.docsAndPositions(MultiFields.getLiveDocs(reader), + null, false); + while (positions.nextDoc() != DocsEnum.NO_MORE_DOCS) { + assertTrue((positions.docID() % 2) == 1); + } + + reader.close(); + directory.close(); + target.close(); + } + + public void testOverrideMethods() throws Exception { + boolean fail = false; + for (Method m : FilterAtomicReader.class.getMethods()) { + int mods = m.getModifiers(); + if (Modifier.isStatic(mods) || Modifier.isFinal(mods) || m.isSynthetic()) { + continue; + } + Class declaringClass = m.getDeclaringClass(); + String name = m.getName(); + if (declaringClass != FilterAtomicReader.class && declaringClass != Object.class) { + System.err.println("method is not overridden by FilterIndexReader: " + name); + fail = true; + } + } + assertFalse("FilterIndexReader overrides (or not) some problematic methods; see log above", fail); + } + +} Index: lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java (revision 1243048) +++ lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java (working copy) Property changes on: lucene/core/src/test/org/apache/lucene/index/TestFilterAtomicReader.java ___________________________________________________________________ Added: cvs2svn:cvs-rev ## -0,0 +1 ## +1.9 Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision Added: svn:eol-style ## -0,0 +1 ## +native Index: lucene/core/src/test/org/apache/lucene/index/TestFilterIndexReader.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestFilterIndexReader.java (revision 1243048) +++ lucene/core/src/test/org/apache/lucene/index/TestFilterIndexReader.java (working copy) @@ -1,197 +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.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashSet; - -import org.apache.lucene.analysis.MockAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.TextField; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.MockDirectoryWrapper; -import org.apache.lucene.util.Bits; -import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.LuceneTestCase; -import org.apache.lucene.util.ReaderUtil; - -public class TestFilterIndexReader extends LuceneTestCase { - - private static class TestReader extends FilterIndexReader { - - /** Filter that only permits terms containing 'e'.*/ - private static class TestFields extends FilterFields { - TestFields(Fields in) { - super(in); - } - @Override - public FieldsEnum iterator() throws IOException { - return new TestFieldsEnum(super.iterator()); - } - @Override - public Terms terms(String field) throws IOException { - return new TestTerms(super.terms(field)); - } - } - - private static class TestTerms extends FilterTerms { - TestTerms(Terms in) { - super(in); - } - - @Override - public TermsEnum iterator(TermsEnum reuse) throws IOException { - return new TestTermsEnum(super.iterator(reuse)); - } - } - - private static class TestFieldsEnum extends FilterFieldsEnum { - TestFieldsEnum(FieldsEnum in) { - super(in); - } - - @Override - public Terms terms() throws IOException { - return new TestTerms(super.terms()); - } - } - - private static class TestTermsEnum extends FilterTermsEnum { - public TestTermsEnum(TermsEnum in) { - super(in); - } - - /** Scan for terms containing the letter 'e'.*/ - @Override - public BytesRef next() throws IOException { - BytesRef text; - while ((text = in.next()) != null) { - if (text.utf8ToString().indexOf('e') != -1) - return text; - } - return null; - } - - @Override - public DocsAndPositionsEnum docsAndPositions(Bits liveDocs, DocsAndPositionsEnum reuse, boolean needsOffsets) throws IOException { - return new TestPositions(super.docsAndPositions(liveDocs, reuse == null ? null : ((FilterDocsAndPositionsEnum) reuse).in, needsOffsets)); - } - } - - /** Filter that only returns odd numbered documents. */ - private static class TestPositions extends FilterDocsAndPositionsEnum { - public TestPositions(DocsAndPositionsEnum in) { - super(in); - } - - /** Scan for odd numbered documents. */ - @Override - public int nextDoc() throws IOException { - int doc; - while ((doc = in.nextDoc()) != NO_MORE_DOCS) { - if ((doc % 2) == 1) - return doc; - } - return NO_MORE_DOCS; - } - } - - public TestReader(IndexReader reader) throws IOException { - super(SlowCompositeReaderWrapper.wrap(reader)); - } - - @Override - public Fields fields() throws IOException { - return new TestFields(super.fields()); - } - } - - /** - * Tests the IndexReader.getFieldNames implementation - * @throws Exception on error - */ - public void testFilterIndexReader() throws Exception { - Directory directory = newDirectory(); - - IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); - - Document d1 = new Document(); - d1.add(newField("default","one two", TextField.TYPE_STORED)); - writer.addDocument(d1); - - Document d2 = new Document(); - d2.add(newField("default","one three", TextField.TYPE_STORED)); - writer.addDocument(d2); - - Document d3 = new Document(); - d3.add(newField("default","two four", TextField.TYPE_STORED)); - writer.addDocument(d3); - - writer.close(); - - Directory target = newDirectory(); - - // We mess with the postings so this can fail: - ((MockDirectoryWrapper) target).setCrossCheckTermVectorsOnClose(false); - - writer = new IndexWriter(target, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))); - IndexReader reader = new TestReader(IndexReader.open(directory)); - writer.addIndexes(reader); - writer.close(); - reader.close(); - reader = IndexReader.open(target); - - TermsEnum terms = MultiFields.getTerms(reader, "default").iterator(null); - while (terms.next() != null) { - assertTrue(terms.term().utf8ToString().indexOf('e') != -1); - } - - assertEquals(TermsEnum.SeekStatus.FOUND, terms.seekCeil(new BytesRef("one"))); - - DocsAndPositionsEnum positions = terms.docsAndPositions(MultiFields.getLiveDocs(reader), - null, false); - while (positions.nextDoc() != DocsEnum.NO_MORE_DOCS) { - assertTrue((positions.docID() % 2) == 1); - } - - reader.close(); - directory.close(); - target.close(); - } - - public void testOverrideMethods() throws Exception { - boolean fail = false; - for (Method m : FilterIndexReader.class.getMethods()) { - int mods = m.getModifiers(); - if (Modifier.isStatic(mods) || Modifier.isFinal(mods) || m.isSynthetic()) { - continue; - } - Class declaringClass = m.getDeclaringClass(); - String name = m.getName(); - if (declaringClass != FilterIndexReader.class && declaringClass != Object.class) { - System.err.println("method is not overridden by FilterIndexReader: " + name); - fail = true; - } - } - assertFalse("FilterIndexReader overrides (or not) some problematic methods; see log above", fail); - } - -} Index: solr/core/src/test/org/apache/solr/search/TestDocSet.java =================================================================== --- solr/core/src/test/org/apache/solr/search/TestDocSet.java (revision 1243048) +++ solr/core/src/test/org/apache/solr/search/TestDocSet.java (working copy) @@ -22,7 +22,7 @@ import java.util.Random; import org.apache.lucene.index.FieldInfos; -import org.apache.lucene.index.FilterIndexReader; +import org.apache.lucene.index.FilterAtomicReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.index.MultiReader; @@ -338,7 +338,7 @@ public IndexReader dummyIndexReader(final int maxDoc) { // TODO FIXME: THIS IS HEAVY BROKEN AND ILLEGAL TO DO (null delegate): - IndexReader r = new FilterIndexReader(null) { + IndexReader r = new FilterAtomicReader(null) { @Override public int maxDoc() { return maxDoc;