/** Drains the weak key references queue. */ @GuardedBy("evictionLock") void drainKeyReferences() { if (!collectKeys()) { return; } Reference<? extends K> keyRef; while ((keyRef = keyReferenceQueue().poll()) != null) { Node<K, V> node = data.get(keyRef); if (node != null) { evictEntry(node, RemovalCause.COLLECTED, 0L); } } }
@Override public @Nullable V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { requireNonNull(key); requireNonNull(value); requireNonNull(remappingFunction); long[] now = { expirationTicker().read() }; Object keyRef = nodeFactory.newReferenceKey(key, keyReferenceQueue()); BiFunction<? super K, ? super V, ? extends V> mergeFunction = (k, oldValue) -> (oldValue == null) ? value : statsAware(remappingFunction).apply(oldValue, value); return remap(key, keyRef, mergeFunction, now, /* computeIfAbsent */ true); }
@Override public @Nullable V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction, boolean recordMiss, boolean recordLoad) { requireNonNull(key); requireNonNull(remappingFunction); long[] now = { expirationTicker().read() }; Object keyRef = nodeFactory.newReferenceKey(key, keyReferenceQueue()); BiFunction<? super K, ? super V, ? extends V> statsAwareRemappingFunction = statsAware(remappingFunction, recordMiss, recordLoad); return remap(key, keyRef, statsAwareRemappingFunction, now, /* computeIfAbsent */ true); }
@Override public @Nullable V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction, boolean recordStats, boolean recordLoad) { requireNonNull(key); requireNonNull(mappingFunction); long now = expirationTicker().read(); // An optimistic fast path to avoid unnecessary locking Node<K, V> node = data.get(nodeFactory.newLookupKey(key)); if (node != null) { V value = node.getValue(); if ((value != null) && !hasExpired(node, now)) { if (!isComputingAsync(node)) { setVariableTime(node, expireAfterRead(node, key, value, expiry(), now)); setAccessTime(node, now); } afterRead(node, now, /* recordHit */ true); return value; } } if (recordStats) { mappingFunction = statsAware(mappingFunction, recordLoad); } Object keyRef = nodeFactory.newReferenceKey(key, keyReferenceQueue()); return doComputeIfAbsent(key, keyRef, mappingFunction, new long[] { now }); }
if (prior == null) { if (node == null) { node = nodeFactory.newNode(key, keyReferenceQueue(), value, valueReferenceQueue(), newWeight, now); setVariableTime(node, expireAfterCreate(key, value, expiry, now));
/** Drains the weak key references queue. */ @GuardedBy("evictionLock") void drainKeyReferences() { if (!collectKeys()) { return; } Reference<? extends K> keyRef; while ((keyRef = keyReferenceQueue().poll()) != null) { Node<K, V> node = data.get(keyRef); if (node != null) { evictEntry(node, RemovalCause.COLLECTED, 0L); } } }
n = nodeFactory.newNode(key, keyReferenceQueue(), newValue[0], valueReferenceQueue(), weight[1], now[0]); setVariableTime(n, expireAfterCreate(key, newValue[0], expiry(), now[0]));
@Override public @Nullable V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { requireNonNull(key); requireNonNull(value); requireNonNull(remappingFunction); long[] now = { expirationTicker().read() }; Object keyRef = nodeFactory.newReferenceKey(key, keyReferenceQueue()); BiFunction<? super K, ? super V, ? extends V> mergeFunction = (k, oldValue) -> (oldValue == null) ? value : statsAware(remappingFunction).apply(oldValue, value); return remap(key, keyRef, mergeFunction, now, /* computeIfAbsent */ true); }
@Override public @Nullable V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction, boolean recordMiss, boolean recordLoad) { requireNonNull(key); requireNonNull(remappingFunction); long[] now = { expirationTicker().read() }; Object keyRef = nodeFactory.newReferenceKey(key, keyReferenceQueue()); BiFunction<? super K, ? super V, ? extends V> statsAwareRemappingFunction = statsAware(remappingFunction, recordMiss, recordLoad); return remap(key, keyRef, statsAwareRemappingFunction, now, /* computeIfAbsent */ true); }
@Override public @Nullable V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction, boolean recordStats, boolean recordLoad) { requireNonNull(key); requireNonNull(mappingFunction); long now = expirationTicker().read(); // An optimistic fast path to avoid unnecessary locking Node<K, V> node = data.get(nodeFactory.newLookupKey(key)); if (node != null) { V value = node.getValue(); if ((value != null) && !hasExpired(node, now)) { if (!isComputingAsync(node)) { setVariableTime(node, expireAfterRead(node, key, value, expiry(), now)); setAccessTime(node, now); } afterRead(node, now, /* recordHit */ true); return value; } } if (recordStats) { mappingFunction = statsAware(mappingFunction, recordLoad); } Object keyRef = nodeFactory.newReferenceKey(key, keyReferenceQueue()); return doComputeIfAbsent(key, keyRef, mappingFunction, new long[] { now }); }
if (prior == null) { if (node == null) { node = nodeFactory.newNode(key, keyReferenceQueue(), value, valueReferenceQueue(), newWeight, now); setVariableTime(node, expireAfterCreate(key, value, expiry, now));
n = nodeFactory.newNode(key, keyReferenceQueue(), newValue[0], valueReferenceQueue(), weight[1], now[0]); setVariableTime(n, expireAfterCreate(key, newValue[0], expiry(), now[0]));