@Override public void recordHits(int count) { try { delegate.recordHits(count); } catch (Throwable t) { logger.log(Level.WARNING, "Exception thrown by stats counter", t); } }
@Override public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction, boolean recordStats, boolean recordLoad) { requireNonNull(mappingFunction); // optimistic fast path due to computeIfAbsent always locking V value = data.get(key); if (value != null) { if (recordStats) { statsCounter.recordHits(1); } return value; } boolean[] missed = new boolean[1]; value = data.computeIfAbsent(key, k -> { // Do not communicate to CacheWriter on a load missed[0] = true; return recordStats ? statsAware(mappingFunction, recordLoad).apply(key) : mappingFunction.apply(key); }); if (!missed[0] && recordStats) { statsCounter.recordHits(1); } return value; }
@Override public @Nullable V getIfPresent(Object key, boolean recordStats) { V value = data.get(key); if (recordStats) { if (value == null) { statsCounter.recordMisses(1); } else { statsCounter.recordHits(1); } } return value; }
@Override public Map<K, V> getAllPresent(Iterable<?> keys) { Set<Object> uniqueKeys = new LinkedHashSet<>(); for (Object key : keys) { uniqueKeys.add(key); } int misses = 0; Map<Object, Object> result = new LinkedHashMap<>(uniqueKeys.size()); for (Object key : uniqueKeys) { Object value = data.get(key); if (value == null) { misses++; } else { result.put(key, value); } } statsCounter.recordMisses(misses); statsCounter.recordHits(result.size()); @SuppressWarnings("unchecked") Map<K, V> castedResult = (Map<K, V>) result; return Collections.unmodifiableMap(castedResult); }
@Override public Map<K, V> getAllPresent(Iterable<?> keys) { Set<Object> uniqueKeys = new LinkedHashSet<>(); for (Object key : keys) { uniqueKeys.add(key); } int misses = 0; Map<Object, Object> result = new LinkedHashMap<>(); for (Object key : uniqueKeys) { CompletableFuture<V> future = asyncCache().cache().get(key); Object value = Async.getIfReady(future); if (value == null) { misses++; } else { result.put(key, value); } } asyncCache().cache().statsCounter().recordMisses(misses); asyncCache().cache().statsCounter().recordHits(result.size()); @SuppressWarnings("unchecked") Map<K, V> castedResult = (Map<K, V>) result; return Collections.unmodifiableMap(castedResult); }
cache().statsCounter().recordHits(futures.size() - proxies.size()); if (proxies.isEmpty()) { return composeResult(futures);
statsCounter().recordHits(result.size());
@Test public void disabled() { StatsCounter counter = DisabledStatsCounter.INSTANCE; counter.recordHits(1); counter.recordMisses(1); counter.recordLoadSuccess(1); counter.recordLoadFailure(1); assertThat(counter.snapshot(), is(new CacheStats(0, 0, 0, 0, 0, 0, 0))); assertThat(counter.toString(), is(new CacheStats(0, 0, 0, 0, 0, 0, 0).toString())); for (DisabledStatsCounter type : DisabledStatsCounter.values()) { assertThat(DisabledStatsCounter.valueOf(type.name()), is(counter)); } }
/** * Performs the post-processing work required after a read. * * @param node the entry in the page replacement policy * @param now the current time, in nanoseconds * @param recordHit if the hit count should be incremented */ void afterRead(Node<K, V> node, long now, boolean recordHit) { if (recordHit) { statsCounter().recordHits(1); } boolean delayable = skipReadBuffer() || (readBuffer.offer(node) != Buffer.FULL); if (shouldDrainBuffers(delayable)) { scheduleDrainBuffers(); } refreshIfNeeded(node, now); }
@Test public void guarded_exception() { StatsCounter statsCounter = Mockito.mock(StatsCounter.class); when(statsCounter.snapshot()).thenThrow(new NullPointerException()); doThrow(NullPointerException.class).when(statsCounter).recordEviction(); doThrow(NullPointerException.class).when(statsCounter).recordHits(anyInt()); doThrow(NullPointerException.class).when(statsCounter).recordMisses(anyInt()); doThrow(NullPointerException.class).when(statsCounter).recordEviction(anyInt()); doThrow(NullPointerException.class).when(statsCounter).recordLoadSuccess(anyLong()); doThrow(NullPointerException.class).when(statsCounter).recordLoadFailure(anyLong()); StatsCounter guarded = StatsCounter.guardedStatsCounter(statsCounter); guarded.recordHits(1); guarded.recordMisses(1); guarded.recordEviction(); guarded.recordEviction(10); guarded.recordLoadSuccess(1); guarded.recordLoadFailure(1); assertThat(guarded.snapshot(), is(CacheStats.empty())); verify(statsCounter).recordHits(1); verify(statsCounter).recordMisses(1); verify(statsCounter).recordEviction(); verify(statsCounter).recordEviction(10); verify(statsCounter).recordLoadSuccess(1); verify(statsCounter).recordLoadFailure(1); } }
@Test public void guarded() { StatsCounter counter = StatsCounter.guardedStatsCounter(new ConcurrentStatsCounter()); counter.recordHits(1); counter.recordMisses(1); counter.recordEviction(); counter.recordEviction(10); counter.recordLoadSuccess(1); counter.recordLoadFailure(1); CacheStats expected = new CacheStats(1, 1, 1, 1, 2, 2, 10); assertThat(counter.snapshot(), is(expected)); assertThat(counter.toString(), is(expected.toString())); assertThat(counter.snapshot().toString(), is(expected.toString())); }
@Test public void concurrent() { StatsCounter counter = new ConcurrentStatsCounter(); ConcurrentTestHarness.timeTasks(5, () -> { counter.recordHits(1); counter.recordMisses(1); counter.recordEviction(); counter.recordEviction(10); counter.recordLoadSuccess(1); counter.recordLoadFailure(1); }); assertThat(counter.snapshot(), is(new CacheStats(5, 5, 5, 5, 10, 10, 50))); }
@Override public void recordHits(int count) { try { delegate.recordHits(count); } catch (Throwable t) { logger.log(Level.WARNING, "Exception thrown by stats counter", t); } }
@Override public @Nullable V getIfPresent(Object key, boolean recordStats) { V value = data.get(key); if (recordStats) { if (value == null) { statsCounter.recordMisses(1); } else { statsCounter.recordHits(1); } } return value; }
@Override public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction, boolean recordStats, boolean recordLoad) { requireNonNull(mappingFunction); // optimistic fast path due to computeIfAbsent always locking V value = data.get(key); if (value != null) { if (recordStats) { statsCounter.recordHits(1); } return value; } boolean[] missed = new boolean[1]; value = data.computeIfAbsent(key, k -> { // Do not communicate to CacheWriter on a load missed[0] = true; return recordStats ? statsAware(mappingFunction, recordLoad).apply(key) : mappingFunction.apply(key); }); if (!missed[0] && recordStats) { statsCounter.recordHits(1); } return value; }
@Override public Map<K, V> getAllPresent(Iterable<?> keys) { Set<Object> uniqueKeys = new LinkedHashSet<>(); for (Object key : keys) { uniqueKeys.add(key); } int misses = 0; Map<Object, Object> result = new LinkedHashMap<>(uniqueKeys.size()); for (Object key : uniqueKeys) { Object value = data.get(key); if (value == null) { misses++; } else { result.put(key, value); } } statsCounter.recordMisses(misses); statsCounter.recordHits(result.size()); @SuppressWarnings("unchecked") Map<K, V> castedResult = (Map<K, V>) result; return Collections.unmodifiableMap(castedResult); }
cache.statsCounter().recordHits(futures.size() - proxies.size()); if (proxies.isEmpty()) { return composeResult(futures);
statsCounter().recordHits(result.size());
/** * Performs the post-processing work required after a read. * * @param node the entry in the page replacement policy * @param now the current time, in nanoseconds * @param recordHit if the hit count should be incremented */ void afterRead(Node<K, V> node, long now, boolean recordHit) { if (recordHit) { statsCounter().recordHits(1); } boolean delayable = skipReadBuffer() || (readBuffer.offer(node) != Buffer.FULL); if (shouldDrainBuffers(delayable)) { scheduleDrainBuffers(); } refreshIfNeeded(node, now); }