-make more methods and the exceptions work, adding test cases for these

-adding a warning to the javadoc that the user is responsible for keeping the indexes in sync


git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@231343 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Daniel Naber 2005-08-10 22:39:26 +00:00
parent 1e5c36f315
commit e46b8070a6
2 changed files with 79 additions and 16 deletions

View File

@ -16,12 +16,20 @@ package org.apache.lucene.index;
* limitations under the License.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.store.Directory;
import java.io.IOException;
import java.util.*;
/** An IndexReader which reads multiple, parallel indexes. Each index added
* must have the same number of documents, but typically each contains
@ -33,11 +41,17 @@ import java.util.*;
* change rarely and small fields that change more frequently. The smaller
* fields may be re-indexed in a new index and both indexes may be searched
* together.
*
* <p><strong>Warning:</strong> It is up to you to make sure all indexes
* are created and modified the same way. For example, if you add
* documents to one index, you need to add the same documents in the
* same order to the other indexes. <em>Failure to do so will result in
* undefined behavior</em>.
*/
public class ParallelReader extends IndexReader {
private ArrayList readers = new ArrayList();
private List readers = new ArrayList();
private SortedMap fieldToReader = new TreeMap();
private ArrayList storedFieldReaders = new ArrayList();
private List storedFieldReaders = new ArrayList();
private int maxDoc;
private int numDocs;
@ -53,7 +67,13 @@ public class ParallelReader extends IndexReader {
/** Add an IndexReader whose stored fields will not be returned. This can
* accellerate search when stored fields are only needed from a subset of
* the IndexReaders. */
* the IndexReaders.
*
* @throws IllegalArgumentException if not all indexes contain the same number
* of documents
* @throws IllegalArgumentException if not all indexes have the same value
* of {@link IndexReader#maxDoc()}
*/
public void add(IndexReader reader, boolean ignoreStoredFields)
throws IOException {
@ -70,7 +90,7 @@ public class ParallelReader extends IndexReader {
throw new IllegalArgumentException
("All readers must have same numDocs: "+numDocs+"!="+reader.numDocs());
Iterator i = reader.getFieldNames().iterator();
Iterator i = reader.getFieldNames(IndexReader.FieldOption.ALL).iterator();
while (i.hasNext()) { // update fieldToReader map
String field = (String)i.next();
if (fieldToReader.get(field) == null)
@ -79,10 +99,9 @@ public class ParallelReader extends IndexReader {
if (!ignoreStoredFields)
storedFieldReaders.add(reader); // add to storedFieldReaders
readers.add(reader);
}
public int numDocs() { return numDocs; }
public int maxDoc() { return maxDoc; }

View File

@ -17,6 +17,7 @@ package org.apache.lucene.index;
*/
import java.io.IOException;
import java.util.Collection;
import junit.framework.TestCase;
@ -54,7 +55,42 @@ public class TestParallelReader extends TestCase {
bq1.add(new TermQuery(new Term("f1", "v1")), Occur.MUST);
bq1.add(new TermQuery(new Term("f4", "v1")), Occur.MUST);
queryTest(bq1);
}
public void testFieldNames() throws Exception {
Directory dir1 = getDir1();
Directory dir2 = getDir2();
ParallelReader pr = new ParallelReader();
pr.add(IndexReader.open(dir1));
pr.add(IndexReader.open(dir2));
Collection fieldNames = pr.getFieldNames(IndexReader.FieldOption.ALL);
assertEquals(4, fieldNames.size());
assertTrue(fieldNames.contains("f1"));
assertTrue(fieldNames.contains("f2"));
assertTrue(fieldNames.contains("f3"));
assertTrue(fieldNames.contains("f4"));
}
public void testIncompatibleIndexes() throws IOException {
// two documents:
Directory dir1 = getDir1();
// one document only:
Directory dir2 = new RAMDirectory();
IndexWriter w2 = new IndexWriter(dir2, new StandardAnalyzer(), true);
Document d3 = new Document();
d3.add(new Field("f3", "v1", Field.Store.YES, Field.Index.TOKENIZED));
w2.addDocument(d3);
w2.close();
ParallelReader pr = new ParallelReader();
pr.add(IndexReader.open(dir1));
try {
pr.add(IndexReader.open(dir2));
fail("didn't get exptected exception: indexes don't have same number of documents");
} catch (IllegalArgumentException e) {
// expected exception
}
}
private void queryTest(Query query) throws IOException {
@ -95,6 +131,15 @@ public class TestParallelReader extends TestCase {
// Fields 1 & 2 in one index, 3 & 4 in other, with ParallelReader:
private Searcher parallel() throws IOException {
Directory dir1 = getDir1();
Directory dir2 = getDir2();
ParallelReader pr = new ParallelReader();
pr.add(IndexReader.open(dir1));
pr.add(IndexReader.open(dir2));
return new IndexSearcher(pr);
}
private Directory getDir1() throws IOException {
Directory dir1 = new RAMDirectory();
IndexWriter w1 = new IndexWriter(dir1, new StandardAnalyzer(), true);
Document d1 = new Document();
@ -106,7 +151,10 @@ public class TestParallelReader extends TestCase {
d2.add(new Field("f2", "v2", Field.Store.YES, Field.Index.TOKENIZED));
w1.addDocument(d2);
w1.close();
return dir1;
}
private Directory getDir2() throws IOException {
Directory dir2 = new RAMDirectory();
IndexWriter w2 = new IndexWriter(dir2, new StandardAnalyzer(), true);
Document d3 = new Document();
@ -118,11 +166,7 @@ public class TestParallelReader extends TestCase {
d4.add(new Field("f4", "v2", Field.Store.YES, Field.Index.TOKENIZED));
w2.addDocument(d4);
w2.close();
ParallelReader pr = new ParallelReader();
pr.add(IndexReader.open(dir1));
pr.add(IndexReader.open(dir2));
return new IndexSearcher(pr);
return dir2;
}
}