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
|
OpenBitSet, due to an inefficiency in how the underlying storage is
|
||||||
reallocated. (Nadav Har'El via Mike McCandless)
|
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
|
New features
|
||||||
|
|
||||||
* LUCENE-1411: Added expert API to open an IndexWriter on a prior
|
* LUCENE-1411: Added expert API to open an IndexWriter on a prior
|
||||||
|
|
|
@ -472,7 +472,12 @@ public class ParallelReader extends IndexReader {
|
||||||
private TermEnum termEnum;
|
private TermEnum termEnum;
|
||||||
|
|
||||||
public ParallelTermEnum() throws IOException {
|
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)
|
if (field != null)
|
||||||
termEnum = ((IndexReader)fieldToReader.get(field)).terms();
|
termEnum = ((IndexReader)fieldToReader.get(field)).terms();
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,11 +156,13 @@ final class TermVectorsWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2nd pass: write field pointers to tvd
|
// 2nd pass: write field pointers to tvd
|
||||||
long lastFieldPointer = fieldPointers[0];
|
if (numFields > 1) {
|
||||||
for (int i=1; i<numFields; i++) {
|
long lastFieldPointer = fieldPointers[0];
|
||||||
final long fieldPointer = fieldPointers[i];
|
for (int i=1; i<numFields; i++) {
|
||||||
tvd.writeVLong(fieldPointer-lastFieldPointer);
|
final long fieldPointer = fieldPointers[i];
|
||||||
lastFieldPointer = fieldPointer;
|
tvd.writeVLong(fieldPointer-lastFieldPointer);
|
||||||
|
lastFieldPointer = fieldPointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
tvd.writeVInt(0);
|
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