diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/WeakLockFreeCache.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/WeakLockFreeCache.java index b7cb827676..641524a0ad 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/WeakLockFreeCache.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/WeakLockFreeCache.java @@ -18,27 +18,7 @@ final class WeakLockFreeCache implements Cache { @Override public V computeIfAbsent(K key, Function mappingFunction) { - V value = get(key); - if (value != null) { - return value; - } - // Best we can do, we don't expect high contention with this implementation. Note, this - // prevents executing mappingFunction twice but it does not prevent executing mappingFunction - // if there is a concurrent put operation as would be the case for ConcurrentHashMap. However, - // we would never expect an order guarantee in this case anyways so it still has the same - // safety. - synchronized (delegate) { - value = get(key); - if (value != null) { - return value; - } - value = mappingFunction.apply(key); - V previous = delegate.putIfAbsent(key, value); - if (previous != null) { - return previous; - } - return value; - } + return delegate.computeIfAbsent(key, mappingFunction); } @Override diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/internal/weaklockfree/AbstractWeakConcurrentMap.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/internal/weaklockfree/AbstractWeakConcurrentMap.java index ffe13564d5..4f4969e7dc 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/internal/weaklockfree/AbstractWeakConcurrentMap.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/cache/internal/weaklockfree/AbstractWeakConcurrentMap.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Function; import javax.annotation.Nullable; /** @@ -161,6 +162,22 @@ abstract class AbstractWeakConcurrentMap extends ReferenceQueue return previous == null ? target.putIfAbsent(new WeakKey<>(key, this), value) : previous; } + public V computeIfAbsent(K key, Function mappingFunction) { + if (key == null || mappingFunction == null) { + throw new NullPointerException(); + } + V previous; + L lookupKey = getLookupKey(key); + try { + previous = target.get(lookupKey); + } finally { + resetLookupKey(lookupKey); + } + return previous == null + ? target.computeIfAbsent(new WeakKey<>(key, this), ignored -> mappingFunction.apply(key)) + : previous; + } + /** * @param key The key of the entry. * @param value The value of the entry.