@GuardedBy("this") void enqueueNotification( @NullableDecl K key, int hash, @NullableDecl V value, int weight, RemovalCause cause) { totalWeight -= weight; if (cause.wasEvicted()) { statsCounter.recordEviction(); } if (map.removalNotificationQueue != DISCARDING_QUEUE) { RemovalNotification<K, V> notification = RemovalNotification.create(key, value, cause); map.removalNotificationQueue.offer(notification); } }
globalStatsCounter.recordHits(hits); globalStatsCounter.recordMisses(misses);
} finally { if (!success) { globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); throw new InvalidCacheLoadException(loader + " returned null map from loadAll"); globalStatsCounter.recordLoadException(stopwatch.elapsed(NANOSECONDS)); throw new InvalidCacheLoadException(loader + " returned null keys or values from loadAll"); globalStatsCounter.recordLoadSuccess(stopwatch.elapsed(NANOSECONDS)); return result;
} else { recordLockedRead(e, now); statsCounter.recordHits(1); statsCounter.recordMisses(1);
if (value != null) { recordRead(e, now); statsCounter.recordHits(1); return scheduleRefresh(e, key, hash, value, now, loader);
V waitForLoadingValue(ReferenceEntry<K, V> e, K key, ValueReference<K, V> valueReference) throws ExecutionException { if (!valueReference.isLoading()) { throw new AssertionError(); } checkState(!Thread.holdsLock(e), "Recursive load of: %s", key); // don't consider expiration as we're concurrent with loading try { V value = valueReference.waitForValue(); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } // re-read ticker now that loading has completed long now = map.ticker.read(); recordRead(e, now); return value; } finally { statsCounter.recordMisses(1); } }
ImmutableMap<K, V> getAllPresent(Iterable<?> keys) { int hits = 0; int misses = 0; Map<K, V> result = Maps.newLinkedHashMap(); for (Object key : keys) { V value = get(key); if (value == null) { misses++; } else { // TODO(fry): store entry key instead of query key @SuppressWarnings("unchecked") K castKey = (K) key; result.put(castKey, value); hits++; } } globalStatsCounter.recordHits(hits); globalStatsCounter.recordMisses(misses); return ImmutableMap.copyOf(result); }
/** Waits uninterruptibly for {@code newValue} to be loaded, and then records loading stats. */ V getAndRecordStats( K key, int hash, LoadingValueReference<K, V> loadingValueReference, ListenableFuture<V> newValue) throws ExecutionException { V value = null; try { value = getUninterruptibly(newValue); if (value == null) { throw new InvalidCacheLoadException("CacheLoader returned null for key " + key + "."); } statsCounter.recordLoadSuccess(loadingValueReference.elapsedNanos()); storeLoadedValue(key, hash, loadingValueReference, value); return value; } finally { if (value == null) { statsCounter.recordLoadException(loadingValueReference.elapsedNanos()); removeLoadingValue(key, hash, loadingValueReference); } } }
@NullableDecl public V getIfPresent(Object key) { int hash = hash(checkNotNull(key)); V value = segmentFor(hash).get(key, hash); if (value == null) { globalStatsCounter.recordMisses(1); } else { globalStatsCounter.recordHits(1); } return value; }
/** Increments all counters by the values in {@code other}. */ public void incrementBy(StatsCounter other) { CacheStats otherStats = other.snapshot(); hitCount.add(otherStats.hitCount()); missCount.add(otherStats.missCount()); loadSuccessCount.add(otherStats.loadSuccessCount()); loadExceptionCount.add(otherStats.loadExceptionCount()); totalLoadTime.add(otherStats.totalLoadTime()); evictionCount.add(otherStats.evictionCount()); } }