Weak cache optimization (#5344)

This commit is contained in:
Trask Stalnaker 2022-02-11 09:31:34 -08:00 committed by GitHub
parent 36b758e600
commit 54e6b1223e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 21 deletions

View File

@ -18,27 +18,7 @@ final class WeakLockFreeCache<K, V> implements Cache<K, V> {
@Override @Override
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
V value = get(key); return delegate.computeIfAbsent(key, mappingFunction);
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;
}
} }
@Override @Override

View File

@ -33,6 +33,7 @@ import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.function.Function;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
@ -161,6 +162,22 @@ abstract class AbstractWeakConcurrentMap<K, V, L> extends ReferenceQueue<K>
return previous == null ? target.putIfAbsent(new WeakKey<>(key, this), value) : previous; return previous == null ? target.putIfAbsent(new WeakKey<>(key, this), value) : previous;
} }
public V computeIfAbsent(K key, Function<? super K, ? extends V> 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 key The key of the entry.
* @param value The value of the entry. * @param value The value of the entry.