Skip to content

Commit 43f3032

Browse files
Inline some methods into Releasables (#123273)
Bit of a random find. Looks like we're effectively spending something like ~0.5% of the total CPU time on resolving virtual calls for these methods. Inlining `IOUtils` reduces their size quite a bit, removes dead-code for rethrowing `IOException` that is never actually thrown and hopefully as a result improve compilation a little here.
1 parent 731a412 commit 43f3032

File tree

1 file changed

+35
-18
lines changed

1 file changed

+35
-18
lines changed

libs/core/src/main/java/org/elasticsearch/core/Releasables.java

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
package org.elasticsearch.core;
1111

12-
import java.io.IOException;
13-
import java.io.UncheckedIOException;
1412
import java.util.Arrays;
1513
import java.util.Iterator;
1614
import java.util.concurrent.atomic.AtomicReference;
@@ -21,11 +19,17 @@ public enum Releasables {
2119

2220
/** Release the provided {@link Releasable}s. */
2321
public static void close(Iterable<? extends Releasable> releasables) {
24-
try {
25-
// this does the right thing with respect to add suppressed and not wrapping errors etc.
26-
IOUtils.close(releasables);
27-
} catch (IOException e) {
28-
throw new UncheckedIOException(e);
22+
RuntimeException firstException = null;
23+
for (final Releasable releasable : releasables) {
24+
try {
25+
close(releasable);
26+
} catch (RuntimeException e) {
27+
firstException = useOrSuppress(firstException, e);
28+
}
29+
}
30+
31+
if (firstException != null) {
32+
throw firstException;
2933
}
3034
}
3135

@@ -38,7 +42,18 @@ public static void close(@Nullable Releasable releasable) {
3842

3943
/** Release the provided {@link Releasable}s. */
4044
public static void close(Releasable... releasables) {
41-
close(true, releasables);
45+
RuntimeException firstException = null;
46+
for (final Releasable releasable : releasables) {
47+
try {
48+
close(releasable);
49+
} catch (RuntimeException e) {
50+
firstException = useOrSuppress(firstException, e);
51+
}
52+
}
53+
54+
if (firstException != null) {
55+
throw firstException;
56+
}
4257
}
4358

4459
/** Release the provided {@link Releasable}s expecting no exception to by thrown by any of them. */
@@ -63,19 +78,21 @@ public static void closeExpectNoException(Releasable releasable) {
6378

6479
/** Release the provided {@link Releasable}s, ignoring exceptions. */
6580
public static void closeWhileHandlingException(Releasable... releasables) {
66-
close(false, releasables);
81+
for (final Releasable releasable : releasables) {
82+
try {
83+
close(releasable);
84+
} catch (RuntimeException e) {
85+
// ignored
86+
}
87+
}
6788
}
6889

69-
/** Release the provided {@link Releasable}s, ignoring exceptions if <code>success</code> is {@code false}. */
70-
private static void close(boolean success, Releasable... releasables) {
71-
try {
72-
// this does the right thing with respect to add suppressed and not wrapping errors etc.
73-
IOUtils.close(releasables);
74-
} catch (IOException e) {
75-
if (success) {
76-
throw new UncheckedIOException(e);
77-
}
90+
private static RuntimeException useOrSuppress(RuntimeException firstException, RuntimeException e) {
91+
if (firstException == null || firstException == e) {
92+
return e;
7893
}
94+
firstException.addSuppressed(e);
95+
return firstException;
7996
}
8097

8198
/** Wrap several releasables into a single one. This is typically useful for use with try-with-resources: for example let's assume

0 commit comments

Comments
 (0)