Index: lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java (working copy) @@ -0,0 +1,111 @@ +package org.apache.lucene.index; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; + +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.ReaderUtil; + +/** Base class for implementing {@link CompositeReader}s based on an array + * of sub-readers. The implementing class has to add code for + * correctly refcounting and closing the sub-readers. + */ +public abstract class BaseCompositeReader extends CompositeReader { + protected final R[] subReaders; + protected final int[] starts; // 1st docno for each reader + private final int maxDoc; + private final int numDocs; + private final boolean hasDeletions; + + protected BaseCompositeReader(R[] subReaders) throws IOException { + this.subReaders = subReaders; + starts = new int[subReaders.length + 1]; // build starts array + int maxDoc = 0, numDocs = 0; + boolean hasDeletions = false; + for (int i = 0; i < subReaders.length; i++) { + starts[i] = maxDoc; + final IndexReader r = subReaders[i]; + maxDoc += r.maxDoc(); // compute maxDocs + numDocs += r.numDocs(); // compute numDocs + if (r.hasDeletions()) { + hasDeletions = true; + } + r.registerParentReader(this); + } + starts[subReaders.length] = maxDoc; + this.maxDoc = maxDoc; + this.numDocs = numDocs; + this.hasDeletions = hasDeletions; + } + + @Override + public final Fields getTermVectors(int docID) throws IOException { + ensureOpen(); + final int i = readerIndex(docID); // find subreader num + return subReaders[i].getTermVectors(docID - starts[i]); // dispatch to subreader + } + + @Override + public final int numDocs() { + // Don't call ensureOpen() here (it could affect performance) + return numDocs; + } + + @Override + public final int maxDoc() { + // Don't call ensureOpen() here (it could affect performance) + return maxDoc; + } + + @Override + public final void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { + ensureOpen(); + final int i = readerIndex(docID); // find subreader num + subReaders[i].document(docID - starts[i], visitor); // dispatch to subreader + } + + @Override + public final boolean hasDeletions() { + // Don't call ensureOpen() here (it could affect performance) + return hasDeletions; + } + + @Override + public final int docFreq(String field, BytesRef t) throws IOException { + ensureOpen(); + int total = 0; // sum freqs in subreaders + for (int i = 0; i < subReaders.length; i++) { + total += subReaders[i].docFreq(field, t); + } + return total; + } + + /** Helper method for subclasses to get the corresponding reader for a doc ID */ + protected final int readerIndex(int docID) { + if (docID < 0 || docID >= maxDoc) { + throw new IllegalArgumentException("docID must be >= 0 and < maxDoc=" + maxDoc + " (got docID=" + docID + ")"); + } + return ReaderUtil.subIndex(docID, this.starts); + } + + @Override + public final R[] getSequentialSubReaders() { + return subReaders; + } +} Index: lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java (revision 1297433) +++ lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java (working copy) Property changes on: lucene/core/src/java/org/apache/lucene/index/BaseCompositeReader.java ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: lucene/core/src/java/org/apache/lucene/index/BaseMultiReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/BaseMultiReader.java (revision 1297433) +++ lucene/core/src/java/org/apache/lucene/index/BaseMultiReader.java (working copy) @@ -1,107 +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 org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.ReaderUtil; - -abstract class BaseMultiReader extends CompositeReader { - protected final R[] subReaders; - protected final int[] starts; // 1st docno for each reader - private final int maxDoc; - private final int numDocs; - private final boolean hasDeletions; - - protected BaseMultiReader(R[] subReaders) throws IOException { - this.subReaders = subReaders; - starts = new int[subReaders.length + 1]; // build starts array - int maxDoc = 0, numDocs = 0; - boolean hasDeletions = false; - for (int i = 0; i < subReaders.length; i++) { - starts[i] = maxDoc; - final IndexReader r = subReaders[i]; - maxDoc += r.maxDoc(); // compute maxDocs - numDocs += r.numDocs(); // compute numDocs - if (r.hasDeletions()) { - hasDeletions = true; - } - r.registerParentReader(this); - } - starts[subReaders.length] = maxDoc; - this.maxDoc = maxDoc; - this.numDocs = numDocs; - this.hasDeletions = hasDeletions; - } - - @Override - public final Fields getTermVectors(int docID) throws IOException { - ensureOpen(); - final int i = readerIndex(docID); // find segment num - return subReaders[i].getTermVectors(docID - starts[i]); // dispatch to segment - } - - @Override - public final int numDocs() { - // Don't call ensureOpen() here (it could affect performance) - return numDocs; - } - - @Override - public final int maxDoc() { - // Don't call ensureOpen() here (it could affect performance) - return maxDoc; - } - - @Override - public final void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException { - ensureOpen(); - final int i = readerIndex(docID); // find segment num - subReaders[i].document(docID - starts[i], visitor); // dispatch to segment reader - } - - @Override - public final boolean hasDeletions() { - // Don't call ensureOpen() here (it could affect performance) - return hasDeletions; - } - - @Override - public final int docFreq(String field, BytesRef t) throws IOException { - ensureOpen(); - int total = 0; // sum freqs in segments - for (int i = 0; i < subReaders.length; i++) { - total += subReaders[i].docFreq(field, t); - } - return total; - } - - /** Helper method for subclasses to get the corresponding reader for a doc ID */ - protected final int readerIndex(int docID) { - if (docID < 0 || docID >= maxDoc) { - throw new IllegalArgumentException("docID must be >= 0 and < maxDoc=" + maxDoc + " (got docID=" + docID + ")"); - } - return ReaderUtil.subIndex(docID, this.starts); - } - - @Override - public final R[] getSequentialSubReaders() { - return subReaders; - } -} Index: lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java (revision 1297433) +++ lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java (working copy) @@ -48,13 +48,8 @@ synchronization, you should not synchronize on the IndexReader instance; use your own (non-Lucene) objects instead. - -

Please note: This class extends from an internal (invisible) - superclass that is generic: The type parameter {@code R} is - {@link AtomicReader}, see {@link #subReaders} and - {@link #getSequentialSubReaders}. */ -public abstract class DirectoryReader extends BaseMultiReader { +public abstract class DirectoryReader extends BaseCompositeReader { public static final int DEFAULT_TERMS_INDEX_DIVISOR = 1; protected final Directory directory; Index: lucene/core/src/java/org/apache/lucene/index/MultiReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/MultiReader.java (revision 1297433) +++ lucene/core/src/java/org/apache/lucene/index/MultiReader.java (working copy) @@ -19,15 +19,11 @@ import java.io.IOException; -/** An IndexReader which reads multiple indexes, appending - * their content. - -

Please note: This class extends from an internal (invisible) - superclass that is generic: The type parameter {@code R} is - {@link IndexReader}, see {@link #subReaders} and - {@link #getSequentialSubReaders}. +/** An {@link CompositeReader} which reads multiple indexes, appending + * their content. It can be used to create a view on several + * sub-readers (like {@link DirectoryReader}) and execute searches on it. */ -public class MultiReader extends BaseMultiReader { +public class MultiReader extends BaseCompositeReader { private final boolean closeSubReaders; /** Index: lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java (revision 1297433) +++ lucene/core/src/java/org/apache/lucene/index/ParallelCompositeReader.java (working copy) @@ -46,7 +46,7 @@ * by number of documents per segment. If you use different {@link MergePolicy}s * it might happen that the segment structure of your index is no longer predictable. */ -public final class ParallelCompositeReader extends BaseMultiReader { +public final class ParallelCompositeReader extends BaseCompositeReader { private final boolean closeSubReaders; private final Set completeReaderSet = Collections.newSetFromMap(new IdentityHashMap());