From 584471f624b6383ca52df965b41e969352ae6f30 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Wed, 29 May 2024 18:21:39 +0200 Subject: [PATCH] Fix TestIndexWriterOnError.testIOError failure. Pull request #13406 inadvertly broke Lucene's handling of tragic exceptions by stopping after the first `DocValuesProducer` whose `close()` calls throws an exception, instead of keeping calling `close()` on further producers in the list. This moves back to the previous behavior. Closes #13434 --- .../org/apache/lucene/index/SegmentDocValues.java | 14 ++++++++------ .../src/java/org/apache/lucene/util/IOUtils.java | 14 +++++++++++--- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java index 82caf6ab0ef8..5a607c6d67e0 100644 --- a/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java +++ b/lucene/core/src/java/org/apache/lucene/index/SegmentDocValues.java @@ -20,10 +20,10 @@ import org.apache.lucene.codecs.DocValuesFormat; import org.apache.lucene.codecs.DocValuesProducer; import org.apache.lucene.internal.hppc.LongArrayList; -import org.apache.lucene.internal.hppc.LongCursor; import org.apache.lucene.internal.hppc.LongObjectHashMap; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IOContext; +import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.RefCount; /** @@ -76,10 +76,12 @@ synchronized DocValuesProducer getDocValuesProducer( /** Decrement the reference count of the given {@link DocValuesProducer} generations. */ synchronized void decRef(LongArrayList dvProducersGens) throws IOException { - for (LongCursor gen : dvProducersGens) { - RefCount dvp = genDVProducers.get(gen.value); - assert dvp != null : "gen=" + gen; - dvp.decRef(); - } + IOUtils.applyToAll( + dvProducersGens.stream().mapToObj(Long::valueOf), + gen -> { + RefCount dvp = genDVProducers.get(gen); + assert dvp != null : "gen=" + gen; + dvp.decRef(); + }); } } diff --git a/lucene/core/src/java/org/apache/lucene/util/IOUtils.java b/lucene/core/src/java/org/apache/lucene/util/IOUtils.java index 3840eb609486..187a67b13e67 100644 --- a/lucene/core/src/java/org/apache/lucene/util/IOUtils.java +++ b/lucene/core/src/java/org/apache/lucene/util/IOUtils.java @@ -40,6 +40,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Objects; +import java.util.stream.Stream; import org.apache.lucene.store.Directory; /** @@ -460,11 +461,18 @@ public static T useOrSuppress(T first, T second) { * The first exception thrown by the consumer is re-thrown and subsequent exceptions are * suppressed. */ - @SuppressWarnings("StreamToIterable") public static void applyToAll(Collection collection, IOConsumer consumer) throws IOException { + applyToAll(collection.stream(), consumer); + } + + /** + * Applies the consumer to all non-null elements in the stream even if an exception is thrown. The + * first exception thrown by the consumer is re-thrown and subsequent exceptions are suppressed. + */ + @SuppressWarnings("StreamToIterable") + public static void applyToAll(Stream stream, IOConsumer consumer) throws IOException { IOUtils.close( - collection.stream().filter(Objects::nonNull).map(t -> (Closeable) () -> consumer.accept(t)) - ::iterator); + stream.filter(Objects::nonNull).map(t -> (Closeable) () -> consumer.accept(t))::iterator); } }