mirror of https://github.com/apache/lucene.git
LUCENE-1918: fix corner cases (resulting in exceptions) when passing ParallelReader to IndexWriter.addIndexes
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@816602 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7c757a03c1
commit
0cb96adf12
|
@ -559,6 +559,13 @@ Bug fixes
|
|||
OpenBitSet, due to an inefficiency in how the underlying storage is
|
||||
reallocated. (Nadav Har'El via Mike McCandless)
|
||||
|
||||
* LUCENE-1918: Fixed cases where a ParallelReader would
|
||||
generate exceptions on being passed to
|
||||
IndexWriter.addIndexes(IndexReader[]). First case was when the
|
||||
ParallelReader was empty. Second case was when the ParallelReader
|
||||
used to contain documents with TermVectors, but all such documents
|
||||
have been deleted. (Christian Kohlschütter via Mike McCandless)
|
||||
|
||||
New features
|
||||
|
||||
* LUCENE-1411: Added expert API to open an IndexWriter on a prior
|
||||
|
|
|
@ -472,7 +472,12 @@ public class ParallelReader extends IndexReader {
|
|||
private TermEnum termEnum;
|
||||
|
||||
public ParallelTermEnum() throws IOException {
|
||||
field = (String)fieldToReader.firstKey();
|
||||
try {
|
||||
field = (String)fieldToReader.firstKey();
|
||||
} catch(NoSuchElementException e) {
|
||||
// No fields, so keep field == null, termEnum == null
|
||||
return;
|
||||
}
|
||||
if (field != null)
|
||||
termEnum = ((IndexReader)fieldToReader.get(field)).terms();
|
||||
}
|
||||
|
|
|
@ -156,11 +156,13 @@ final class TermVectorsWriter {
|
|||
}
|
||||
|
||||
// 2nd pass: write field pointers to tvd
|
||||
long lastFieldPointer = fieldPointers[0];
|
||||
for (int i=1; i<numFields; i++) {
|
||||
final long fieldPointer = fieldPointers[i];
|
||||
tvd.writeVLong(fieldPointer-lastFieldPointer);
|
||||
lastFieldPointer = fieldPointer;
|
||||
if (numFields > 1) {
|
||||
long lastFieldPointer = fieldPointers[0];
|
||||
for (int i=1; i<numFields; i++) {
|
||||
final long fieldPointer = fieldPointers[i];
|
||||
tvd.writeVLong(fieldPointer-lastFieldPointer);
|
||||
lastFieldPointer = fieldPointer;
|
||||
}
|
||||
}
|
||||
} else
|
||||
tvd.writeVInt(0);
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
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.LuceneTestCase;
|
||||
import org.apache.lucene.util._TestUtil;
|
||||
|
||||
import org.apache.lucene.analysis.SimpleAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Field.Index;
|
||||
import org.apache.lucene.document.Field.Store;
|
||||
import org.apache.lucene.document.Field.TermVector;
|
||||
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
|
||||
import org.apache.lucene.store.MockRAMDirectory;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
/**
|
||||
* Some tests for {@link ParallelReader}s with empty indexes
|
||||
*
|
||||
* @author Christian Kohlschuetter
|
||||
*/
|
||||
public class TestParallelReaderEmptyIndex extends LuceneTestCase {
|
||||
|
||||
/**
|
||||
* Creates two empty indexes and wraps a ParallelReader around. Adding this
|
||||
* reader to a new index should not throw any exception.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testEmptyIndex() throws IOException {
|
||||
RAMDirectory rd1 = new MockRAMDirectory();
|
||||
IndexWriter iw = new IndexWriter(rd1, new SimpleAnalyzer(), true,
|
||||
MaxFieldLength.UNLIMITED);
|
||||
iw.close();
|
||||
|
||||
RAMDirectory rd2 = new MockRAMDirectory(rd1);
|
||||
|
||||
RAMDirectory rdOut = new MockRAMDirectory();
|
||||
|
||||
IndexWriter iwOut = new IndexWriter(rdOut, new SimpleAnalyzer(), true,
|
||||
MaxFieldLength.UNLIMITED);
|
||||
ParallelReader pr = new ParallelReader();
|
||||
pr.add(IndexReader.open(rd1,true));
|
||||
pr.add(IndexReader.open(rd2,true));
|
||||
|
||||
// When unpatched, Lucene crashes here with a NoSuchElementException (caused by ParallelTermEnum)
|
||||
iwOut.addIndexes(new IndexReader[] { pr });
|
||||
|
||||
iwOut.optimize();
|
||||
iwOut.close();
|
||||
_TestUtil.checkIndex(rdOut);
|
||||
rdOut.close();
|
||||
rd1.close();
|
||||
rd2.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates an empty index (numFields=0, numDocs=0) but is marked
|
||||
* to have TermVectors. Adding this index to another index should not throw
|
||||
* any exception.
|
||||
*/
|
||||
public void testEmptyIndexWithVectors() throws IOException {
|
||||
RAMDirectory rd1 = new MockRAMDirectory();
|
||||
{
|
||||
IndexWriter iw = new IndexWriter(rd1, new SimpleAnalyzer(), true,
|
||||
MaxFieldLength.UNLIMITED);
|
||||
Document doc = new Document();
|
||||
doc.add(new Field("test", "", Store.NO, Index.ANALYZED,
|
||||
TermVector.YES));
|
||||
iw.addDocument(doc);
|
||||
doc.add(new Field("test", "", Store.NO, Index.ANALYZED,
|
||||
TermVector.NO));
|
||||
iw.addDocument(doc);
|
||||
iw.close();
|
||||
|
||||
IndexReader ir = IndexReader.open(rd1,false);
|
||||
ir.deleteDocument(0);
|
||||
ir.close();
|
||||
|
||||
iw = new IndexWriter(rd1, new SimpleAnalyzer(), false,
|
||||
MaxFieldLength.UNLIMITED);
|
||||
iw.optimize();
|
||||
iw.close();
|
||||
}
|
||||
|
||||
RAMDirectory rd2 = new MockRAMDirectory();
|
||||
{
|
||||
IndexWriter iw = new IndexWriter(rd2, new SimpleAnalyzer(), true,
|
||||
MaxFieldLength.UNLIMITED);
|
||||
Document doc = new Document();
|
||||
iw.addDocument(doc);
|
||||
iw.close();
|
||||
}
|
||||
|
||||
RAMDirectory rdOut = new MockRAMDirectory();
|
||||
|
||||
IndexWriter iwOut = new IndexWriter(rdOut, new SimpleAnalyzer(), true,
|
||||
MaxFieldLength.UNLIMITED);
|
||||
ParallelReader pr = new ParallelReader();
|
||||
pr.add(IndexReader.open(rd1,true));
|
||||
pr.add(IndexReader.open(rd2,true));
|
||||
|
||||
// When unpatched, Lucene crashes here with an ArrayIndexOutOfBoundsException (caused by TermVectorsWriter)
|
||||
iwOut.addIndexes(new IndexReader[] { pr });
|
||||
|
||||
// ParallelReader closes any IndexReader you added to it:
|
||||
pr.close();
|
||||
|
||||
rd1.close();
|
||||
rd2.close();
|
||||
|
||||
iwOut.optimize();
|
||||
iwOut.close();
|
||||
|
||||
_TestUtil.checkIndex(rdOut);
|
||||
rdOut.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue