diff --git a/lucene/src/java/org/apache/lucene/index/FieldsReader.java b/lucene/src/java/org/apache/lucene/index/FieldsReader.java index f085d33cce1..6ac0d436ffe 100644 --- a/lucene/src/java/org/apache/lucene/index/FieldsReader.java +++ b/lucene/src/java/org/apache/lucene/index/FieldsReader.java @@ -30,9 +30,12 @@ import org.apache.lucene.store.BufferedIndexInput; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.CloseableThreadLocal; +import org.apache.lucene.util.IOUtils; +import java.io.Closeable; import java.io.IOException; import java.io.Reader; +import java.util.ArrayList; /** * Class responsible for access to stored document fields. @@ -41,7 +44,7 @@ import java.io.Reader; * * @lucene.internal */ -public final class FieldsReader implements Cloneable { +public final class FieldsReader implements Cloneable, Closeable { private final static int FORMAT_SIZE = 4; private final FieldInfos fieldInfos; @@ -179,21 +182,11 @@ public final class FieldsReader implements Cloneable { */ public final void close() throws IOException { if (!closed) { - if (fieldsStream != null) { - fieldsStream.close(); - } if (isOriginal) { - if (cloneableFieldsStream != null) { - cloneableFieldsStream.close(); - } - if (cloneableIndexStream != null) { - cloneableIndexStream.close(); - } + IOUtils.closeSafely(false, fieldsStream, indexStream, fieldsStreamTL, cloneableFieldsStream, cloneableIndexStream); + } else { + IOUtils.closeSafely(false, fieldsStream, indexStream, fieldsStreamTL); } - if (indexStream != null) { - indexStream.close(); - } - fieldsStreamTL.close(); closed = true; } } diff --git a/lucene/src/java/org/apache/lucene/index/MultiPerDocValues.java b/lucene/src/java/org/apache/lucene/index/MultiPerDocValues.java index 6e6b6d4e3e2..b94da880d13 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiPerDocValues.java +++ b/lucene/src/java/org/apache/lucene/index/MultiPerDocValues.java @@ -28,6 +28,7 @@ import org.apache.lucene.index.values.IndexDocValues; import org.apache.lucene.index.values.MultiIndexDocValues; import org.apache.lucene.index.values.ValueType; import org.apache.lucene.index.values.MultiIndexDocValues.DocValuesIndex; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.ReaderUtil.Gather; @@ -151,20 +152,7 @@ public class MultiPerDocValues extends PerDocValues { } public void close() throws IOException { - final PerDocValues[] perDocValues = this.subs; - IOException ex = null; - for (PerDocValues values : perDocValues) { - try { - values.close(); - } catch (IOException e) { - if (ex == null) { - ex = e; - } - } - } - if (ex != null) { - throw ex; - } + IOUtils.closeSafely(false, this.subs); } @Override diff --git a/lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java b/lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java index 35f8f94fe32..85341563d40 100644 --- a/lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java +++ b/lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java @@ -25,6 +25,7 @@ import org.apache.lucene.index.codecs.FieldsProducer; import org.apache.lucene.index.codecs.PerDocValues; import org.apache.lucene.store.CompoundFileDirectory; import org.apache.lucene.store.Directory; +import org.apache.lucene.util.IOUtils; /** Holds core readers that are shared (unchanged) when * SegmentReader is cloned or reopened */ @@ -119,33 +120,9 @@ final class SegmentCoreReaders { } synchronized void decRef() throws IOException { - if (ref.decrementAndGet() == 0) { - - if (fields != null) { - fields.close(); - } - - if (perDocProducer != null) { - perDocProducer.close(); - } - - if (termVectorsReaderOrig != null) { - termVectorsReaderOrig.close(); - } - - if (fieldsReaderOrig != null) { - fieldsReaderOrig.close(); - } - - if (cfsReader != null) { - cfsReader.close(); - } - - if (storeCFSReader != null) { - storeCFSReader.close(); - } - + IOUtils.closeSafely(false, fields, perDocProducer, termVectorsReaderOrig, + fieldsReaderOrig, cfsReader, storeCFSReader); // Now, notify any ReaderFinished listeners: if (owner != null) { owner.notifyReaderFinishedListeners(); diff --git a/lucene/src/java/org/apache/lucene/index/SegmentMerger.java b/lucene/src/java/org/apache/lucene/index/SegmentMerger.java index f6f411e5ce3..6b6bc74f153 100644 --- a/lucene/src/java/org/apache/lucene/index/SegmentMerger.java +++ b/lucene/src/java/org/apache/lucene/index/SegmentMerger.java @@ -574,30 +574,36 @@ final class SegmentMerger { final List perDocBits = new ArrayList(); final List perDocBitsStarts = new ArrayList(); int docBase = 0; - for(IndexReader r : readers) { - final int maxDoc = r.maxDoc(); - final PerDocValues producer = r.perDocValues(); - if (producer != null) { - perDocSlices.add(new ReaderUtil.Slice(docBase, maxDoc, perDocProducers.size())); - perDocProducers.add(producer); - perDocBits.add(r.getLiveDocs()); - perDocBitsStarts.add(docBase); + try { + for(IndexReader r : readers) { + final int maxDoc = r.maxDoc(); + final PerDocValues producer = r.perDocValues(); + if (producer != null) { + perDocSlices.add(new ReaderUtil.Slice(docBase, maxDoc, perDocProducers.size())); + perDocProducers.add(producer); + perDocBits.add(r.getLiveDocs()); + perDocBitsStarts.add(docBase); + } + docBase += maxDoc; } - docBase += maxDoc; - } - perDocBitsStarts.add(docBase); - if (!perDocSlices.isEmpty()) { - mergeState.multiLiveDocs = new MultiBits(perDocBits, perDocBitsStarts, true); - final PerDocConsumer docsConsumer = codec - .docsConsumer(new PerDocWriteState(segmentWriteState)); - try { - final MultiPerDocValues multiPerDocValues = new MultiPerDocValues(perDocProducers - .toArray(PerDocValues.EMPTY_ARRAY), perDocSlices - .toArray(ReaderUtil.Slice.EMPTY_ARRAY)); - docsConsumer.merge(mergeState, multiPerDocValues); - } finally { - docsConsumer.close(); + perDocBitsStarts.add(docBase); + if (!perDocSlices.isEmpty()) { + mergeState.multiLiveDocs = new MultiBits(perDocBits, perDocBitsStarts, true); + final PerDocConsumer docsConsumer = codec + .docsConsumer(new PerDocWriteState(segmentWriteState)); + boolean success = false; + try { + final MultiPerDocValues multiPerDocValues = new MultiPerDocValues(perDocProducers + .toArray(PerDocValues.EMPTY_ARRAY), perDocSlices + .toArray(ReaderUtil.Slice.EMPTY_ARRAY)); + docsConsumer.merge(mergeState, multiPerDocValues); + success = true; + } finally { + IOUtils.closeSafely(!success, docsConsumer); + } } + } finally { + IOUtils.closeSafely(false, perDocProducers); } } diff --git a/lucene/src/java/org/apache/lucene/index/TermVectorsReader.java b/lucene/src/java/org/apache/lucene/index/TermVectorsReader.java index 5c8d2e68905..0d6b7dcbaf1 100644 --- a/lucene/src/java/org/apache/lucene/index/TermVectorsReader.java +++ b/lucene/src/java/org/apache/lucene/index/TermVectorsReader.java @@ -22,11 +22,13 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.IOUtils; +import java.io.Closeable; import java.io.IOException; import java.util.Arrays; -class TermVectorsReader implements Cloneable { +class TermVectorsReader implements Cloneable, Closeable { // NOTE: if you make a new format, it must be larger than // the current format @@ -192,14 +194,8 @@ class TermVectorsReader implements Cloneable { return format; } - void close() throws IOException { - // make all effort to close up. Keep the first exception - // and throw it as a new one. - IOException keep = null; - if (tvx != null) try { tvx.close(); } catch (IOException e) { keep = e; } - if (tvd != null) try { tvd.close(); } catch (IOException e) { if (keep == null) keep = e; } - if (tvf != null) try { tvf.close(); } catch (IOException e) { if (keep == null) keep = e; } - if (keep != null) throw (IOException) keep.fillInStackTrace(); + public void close() throws IOException { + IOUtils.closeSafely(false, tvx, tvd, tvf); } /**