Skip to content

Commit de7bb61

Browse files
Optimize CachedSupplier a little (#119563) (#119878)
This thing shows up a lot in profiling many-shards searches and fields caps. This is mainly due to expensive `initResult` but we can at least get a little better cache behavior here on some architectures by saving one volatile read.
1 parent 13c4f5d commit de7bb61

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

server/src/main/java/org/elasticsearch/common/util/CachedSupplier.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
public final class CachedSupplier<T> implements Supplier<T> {
2020

2121
private volatile Supplier<T> supplier;
22-
private volatile T result;
22+
// result does not need to be volatile as we only read it after reading that the supplier got nulled out. Since we null out the
23+
// supplier after setting the result, total store order from an observed volatile write is sufficient to make a plain read safe.
24+
private T result;
2325

2426
public static <R> CachedSupplier<R> wrap(Supplier<R> supplier) {
2527
if (supplier instanceof CachedSupplier<R> c) {
@@ -38,14 +40,18 @@ public T get() {
3840
if (supplier == null) {
3941
return result;
4042
}
41-
initResult();
42-
return result;
43+
return initResult();
4344
}
4445

45-
private synchronized void initResult() {
46-
if (supplier != null) {
47-
result = supplier.get();
46+
private synchronized T initResult() {
47+
var s = supplier;
48+
if (s != null) {
49+
T res = s.get();
50+
result = res;
4851
supplier = null;
52+
return res;
53+
} else {
54+
return result;
4955
}
5056
}
5157

0 commit comments

Comments
 (0)