LUCENE-3633: Improve DirectoryReader and MultiReader to use IOUtils when IOExceptions occur during opening segments; minor tweaks in BaseMultiReader

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1213016 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2011-12-11 15:43:34 +00:00
parent bf13918e16
commit 377332e696
3 changed files with 34 additions and 32 deletions

View File

@ -75,7 +75,7 @@ abstract class BaseMultiReader<R extends IndexReader> extends IndexReader implem
@Override
public Fields getTermVectors(int docID) throws IOException {
ensureOpen();
int i = readerIndex(docID); // find segment num
final int i = readerIndex(docID); // find segment num
return subReaders[i].getTermVectors(docID - starts[i]); // dispatch to segment
}
@ -86,7 +86,7 @@ abstract class BaseMultiReader<R extends IndexReader> extends IndexReader implem
}
@Override
public int maxDoc() {
public final int maxDoc() {
// Don't call ensureOpen() here (it could affect performance)
return maxDoc;
}
@ -94,13 +94,13 @@ abstract class BaseMultiReader<R extends IndexReader> extends IndexReader implem
@Override
public void document(int docID, StoredFieldVisitor visitor) throws CorruptIndexException, IOException {
ensureOpen();
int i = readerIndex(docID); // find segment num
final int i = readerIndex(docID); // find segment num
subReaders[i].document(docID - starts[i], visitor); // dispatch to segment reader
}
@Override
public boolean hasDeletions() {
ensureOpen();
// Don't call ensureOpen() here (it could affect performance)
return hasDeletions;
}
@ -154,12 +154,11 @@ abstract class BaseMultiReader<R extends IndexReader> extends IndexReader implem
@Override
public ReaderContext getTopReaderContext() {
ensureOpen();
return topLevelContext;
}
@Override
public PerDocValues perDocValues() throws IOException {
throw new UnsupportedOperationException("please use MultiPerDocValues#getPerDocs, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level Fields");
throw new UnsupportedOperationException("please use MultiPerDocValues.getPerDocs, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level Fields");
}
}

View File

@ -31,6 +31,7 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.MapBackedSet;
/**
@ -67,22 +68,17 @@ final class DirectoryReader extends BaseMultiReader<SegmentReader> {
sis.read(directory, segmentFileName);
final SegmentReader[] readers = new SegmentReader[sis.size()];
for (int i = sis.size()-1; i >= 0; i--) {
IOException prior = null;
boolean success = false;
try {
readers[i] = SegmentReader.get(sis.info(i), termInfosIndexDivisor, IOContext.READ);
readers[i].readerFinishedListeners = readerFinishedListeners;
success = true;
} catch(IOException ex) {
prior = ex;
} finally {
if (!success) {
// Close all readers we had opened:
for(i++;i<sis.size();i++) {
try {
readers[i].close();
} catch (Throwable ignore) {
// keep going - we want to clean up as much as possible
}
}
}
if (!success)
IOUtils.closeWhileHandlingException(prior, readers);
}
}
return new DirectoryReader(readers, directory, null, sis, termInfosIndexDivisor,
@ -104,6 +100,7 @@ final class DirectoryReader extends BaseMultiReader<SegmentReader> {
final SegmentInfos segmentInfos = (SegmentInfos) infos.clone();
int infosUpto = 0;
for (int i=0;i<numSegments;i++) {
IOException prior = null;
boolean success = false;
try {
final SegmentInfo info = infos.info(i);
@ -118,17 +115,11 @@ final class DirectoryReader extends BaseMultiReader<SegmentReader> {
segmentInfos.remove(infosUpto);
}
success = true;
} catch(IOException ex) {
prior = ex;
} finally {
if (!success) {
// Close all readers we had opened:
for(SegmentReader reader : readers) {
try {
reader.close();
} catch (Throwable ignore) {
// keep going - we want to clean up as much as possible
}
}
}
if (!success)
IOUtils.closeWhileHandlingException(prior, readers);
}
}
return new DirectoryReader(readers.toArray(new SegmentReader[readers.size()]),
@ -169,6 +160,7 @@ final class DirectoryReader extends BaseMultiReader<SegmentReader> {
}
boolean success = false;
IOException prior = null;
try {
SegmentReader newReader;
if (newReaders[i] == null || infos.info(i).getUseCompoundFile() != newReaders[i].getSegmentInfo().getUseCompoundFile()) {
@ -196,6 +188,8 @@ final class DirectoryReader extends BaseMultiReader<SegmentReader> {
}
}
success = true;
} catch (IOException ex) {
prior = ex;
} finally {
if (!success) {
for (i++; i < infos.size(); i++) {
@ -210,12 +204,14 @@ final class DirectoryReader extends BaseMultiReader<SegmentReader> {
// closing we must decRef it
newReaders[i].decRef();
}
} catch (IOException ignore) {
// keep going - we want to clean up as much as possible
} catch (IOException ex) {
if (prior == null) prior = ex;
}
}
}
}
// throw the first exception
if (prior != null) throw prior;
}
}
return new DirectoryReader(newReaders,

View File

@ -127,13 +127,20 @@ public class MultiReader extends BaseMultiReader<IndexReader> {
@Override
protected synchronized void doClose() throws IOException {
IOException ioe = null;
for (int i = 0; i < subReaders.length; i++) {
if (decrefOnClose[i]) {
subReaders[i].decRef();
} else {
subReaders[i].close();
try {
if (decrefOnClose[i]) {
subReaders[i].decRef();
} else {
subReaders[i].close();
}
} catch (IOException e) {
if (ioe == null) ioe = e;
}
}
// throw the first exception
if (ioe != null) throw ioe;
}
@Override