Index: src/test/org/apache/lucene/index/TestParallelReader.java =================================================================== --- src/test/org/apache/lucene/index/TestParallelReader.java (revision 962932) +++ src/test/org/apache/lucene/index/TestParallelReader.java (working copy) @@ -20,10 +20,16 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.FieldSelectorResult; +import org.apache.lucene.document.LoadFirstFieldSelector; import org.apache.lucene.document.MapFieldSelector; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.IndexSearcher; @@ -100,6 +106,56 @@ assertEquals("v2", doc223.get("f3")); } + /** + * {@link LoadFirstFieldSelector} loads the first field of EACH sub-reader. + * @throws IOException + */ + public void testDocumentLoadFirst() throws IOException { + Directory dir1 = getDir1(); + Directory dir2 = getDir2(); + ParallelReader pr = new ParallelReader(); + pr.add(IndexReader.open(dir1, false)); + pr.add(IndexReader.open(dir2, false)); + + Document doc1 = pr.document(0, new LoadFirstFieldSelector()); + Document doc2 = pr.document(1, new LoadFirstFieldSelector()); + + assertEquals(2, doc1.getFields().size()); + assertEquals(2, doc2.getFields().size()); + + assertEquals("v1", doc1.get("f1")); + assertEquals("v1", doc1.get("f1")); + assertEquals("v2", doc2.get("f3")); + assertEquals("v2", doc2.get("f3")); + } + + public void testDocumentAcceptF2BlockedByBreak() throws IOException { + Directory dir1 = getDir1(); + Directory dir2 = getDir2(); + ParallelReader pr = new ParallelReader(); + pr.add(IndexReader.open(dir1, false)); + pr.add(IndexReader.open(dir2, false)); + final AtomicInteger counter = new AtomicInteger(0); + + // count calls to accept, validating include == false inside the ParallelReader + FieldSelector fs = new FieldSelector() { + private static final long serialVersionUID = 1L; + @Override + public FieldSelectorResult accept(String fieldName) { + counter.incrementAndGet(); + return "f2".equals(fieldName) ? FieldSelectorResult.LOAD : FieldSelectorResult.BREAK; + } + }; + + Document doc1 = pr.document(0, fs); + assertEquals(2, counter.get()); + Document doc2 = pr.document(1, fs); + assertEquals(4, counter.get()); + + assertEquals(0, doc1.getFields().size()); + assertEquals(0, doc2.getFields().size()); + } + public void testIncompatibleIndexes() throws IOException { // two documents: Directory dir1 = getDir1(); Index: src/test/org/apache/lucene/document/TestFieldSelectorResult.java =================================================================== --- src/test/org/apache/lucene/document/TestFieldSelectorResult.java (revision 0) +++ src/test/org/apache/lucene/document/TestFieldSelectorResult.java (revision 0) @@ -0,0 +1,55 @@ +/** + * 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. + */ +package org.apache.lucene.document; + +import org.apache.lucene.util.LuceneTestCase; + +/** + * Test code for the FieldSelectorResult class + */ +public class TestFieldSelectorResult extends LuceneTestCase { + + /** + * Test method for {@link org.apache.lucene.document.FieldSelectorResult#loads}. + */ + public void testIsLoad() { + assertTrue(FieldSelectorResult.LOAD.loads); + assertTrue(FieldSelectorResult.LOAD_AND_BREAK.loads); + // lazy load returns true b/c it "could" be loaded + assertTrue(FieldSelectorResult.LAZY_LOAD.loads); + + assertFalse(FieldSelectorResult.BREAK.loads); + assertFalse(FieldSelectorResult.NO_LOAD.loads); + assertFalse(FieldSelectorResult.SIZE.loads); + assertFalse(FieldSelectorResult.SIZE_AND_BREAK.loads); + } + + /** + * Test method for {@link org.apache.lucene.document.FieldSelectorResult#breaks}. + */ + public void testIsBreak() { + assertTrue(FieldSelectorResult.LOAD_AND_BREAK.breaks); + assertTrue(FieldSelectorResult.BREAK.breaks); + assertTrue(FieldSelectorResult.SIZE_AND_BREAK.breaks); + + assertFalse(FieldSelectorResult.LOAD.breaks); + assertFalse(FieldSelectorResult.LAZY_LOAD.breaks); + assertFalse(FieldSelectorResult.NO_LOAD.breaks); + assertFalse(FieldSelectorResult.SIZE.breaks); + } + +} \ No newline at end of file Index: src/java/org/apache/lucene/index/FieldsReader.java =================================================================== --- src/java/org/apache/lucene/index/FieldsReader.java (revision 962932) +++ src/java/org/apache/lucene/index/FieldsReader.java (working copy) @@ -235,26 +235,30 @@ boolean binary = (bits & FieldsWriter.FIELD_IS_BINARY) != 0; //TODO: Find an alternative approach here if this list continues to grow beyond the //list of 5 or 6 currently here. See Lucene 762 for discussion - if (acceptField.equals(FieldSelectorResult.LOAD)) { - addField(doc, fi, binary, compressed, tokenize); + switch (acceptField) { + case LOAD: + case LOAD_AND_BREAK: + addField(doc, fi, binary, compressed, tokenize); + break; + case LAZY_LOAD: + addFieldLazy(doc, fi, binary, compressed, tokenize); + break; + case SIZE: + skipField(binary, compressed, addFieldSize(doc, fi, binary, compressed)); + break; + case SIZE_AND_BREAK: + addFieldSize(doc, fi, binary, compressed); + break; + case BREAK: + break; + case NO_LOAD: + default: + skipField(binary, compressed); } - else if (acceptField.equals(FieldSelectorResult.LOAD_AND_BREAK)){ - addField(doc, fi, binary, compressed, tokenize); - break;//Get out of this loop - } - else if (acceptField.equals(FieldSelectorResult.LAZY_LOAD)) { - addFieldLazy(doc, fi, binary, compressed, tokenize); - } - else if (acceptField.equals(FieldSelectorResult.SIZE)){ - skipField(binary, compressed, addFieldSize(doc, fi, binary, compressed)); - } - else if (acceptField.equals(FieldSelectorResult.SIZE_AND_BREAK)){ - addFieldSize(doc, fi, binary, compressed); + if (acceptField.breaks) { + // Get out of this loop break; } - else { - skipField(binary, compressed); - } } return doc; Index: src/java/org/apache/lucene/index/ParallelReader.java =================================================================== --- src/java/org/apache/lucene/index/ParallelReader.java (revision 962932) +++ src/java/org/apache/lucene/index/ParallelReader.java (working copy) @@ -21,6 +21,7 @@ import org.apache.lucene.document.FieldSelector; import org.apache.lucene.document.FieldSelectorResult; import org.apache.lucene.document.Fieldable; +import org.apache.lucene.document.LoadFirstFieldSelector; import org.apache.lucene.search.FieldCache; // not great (circular); used only to purge FieldCache entry on close import java.io.IOException; @@ -43,6 +44,9 @@ * documents to one index, you need to add the same documents in the * same order to the other indexes. Failure to do so will result in * undefined behavior. + *
Warning: {@link LoadFirstFieldSelector} will not work
+ * as "expected" with this reader. Instead the first field per subreader is
+ * loaded.
*/
public class ParallelReader extends IndexReader {
private List