@Override public void recordMisses(int count) { try { delegate.recordMisses(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 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); }
/** Sequentially loads each missing entry. */ default Map<K, V> loadSequentially(Iterable<? extends K> keys) { Set<K> uniqueKeys = new LinkedHashSet<>(); for (K key : keys) { uniqueKeys.add(key); } int count = 0; Map<K, V> result = new LinkedHashMap<>(uniqueKeys.size()); try { for (K key : uniqueKeys) { count++; V value = get(key); if (value != null) { result.put(key, value); } } } catch (Throwable t) { cache().statsCounter().recordMisses(uniqueKeys.size() - count); throw t; } return Collections.unmodifiableMap(result); }
@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().recordMisses(proxies.size()); cache().statsCounter().recordHits(futures.size() - proxies.size()); if (proxies.isEmpty()) {
statsCounter().recordMisses(misses); 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)); } }
@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())); }
@Override public @Nullable V getIfPresent(Object key, boolean recordStats) { Node<K, V> node = data.get(nodeFactory.newLookupKey(key)); if (node == null) { if (recordStats) { statsCounter().recordMisses(1); } return null; } V value = node.getValue(); long now = expirationTicker().read(); if (hasExpired(node, now) || (collectValues() && (value == null))) { if (recordStats) { statsCounter().recordMisses(1); } scheduleDrainBuffers(); return null; } if (!isComputingAsync(node)) { @SuppressWarnings("unchecked") K castedKey = (K) key; setAccessTime(node, now); setVariableTime(node, expireAfterRead(node, castedKey, value, expiry(), now)); } afterRead(node, now, recordStats); return value; }
@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))); }
/** Decorates the remapping function to record statistics if enabled. */ default Function<? super K, ? extends V> statsAware( Function<? super K, ? extends V> mappingFunction, boolean recordLoad) { if (!isRecordingStats()) { return mappingFunction; } return key -> { V value; statsCounter().recordMisses(1); long startTime = statsTicker().read(); try { value = mappingFunction.apply(key); } catch (RuntimeException | Error e) { statsCounter().recordLoadFailure(statsTicker().read() - startTime); throw e; } long loadTime = statsTicker().read() - startTime; if (recordLoad) { if (value == null) { statsCounter().recordLoadFailure(loadTime); } else { statsCounter().recordLoadSuccess(loadTime); } } return value; }; }
R result; if ((u == null) && recordMiss) { statsCounter().recordMisses(1);
@Override public void recordMisses(int count) { try { delegate.recordMisses(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 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); }
/** Sequentially loads each missing entry. */ default Map<K, V> loadSequentially(Iterable<? extends K> keys) { Set<K> uniqueKeys = new LinkedHashSet<>(); for (K key : keys) { uniqueKeys.add(key); } int count = 0; Map<K, V> result = new LinkedHashMap<>(uniqueKeys.size()); try { for (K key : uniqueKeys) { count++; V value = get(key); if (value != null) { result.put(key, value); } } } catch (Throwable t) { cache().statsCounter().recordMisses(uniqueKeys.size() - count); throw t; } return Collections.unmodifiableMap(result); }
@Override public @Nullable V getIfPresent(Object key, boolean recordStats) { Node<K, V> node = data.get(nodeFactory.newLookupKey(key)); if (node == null) { if (recordStats) { statsCounter().recordMisses(1); } return null; } long now = expirationTicker().read(); if (hasExpired(node, now)) { if (recordStats) { statsCounter().recordMisses(1); } scheduleDrainBuffers(); return null; } @SuppressWarnings("unchecked") K castedKey = (K) key; V value = node.getValue(); if (!isComputingAsync(node)) { setVariableTime(node, expireAfterRead(node, castedKey, value, expiry(), now)); setAccessTime(node, now); } afterRead(node, now, recordStats); return value; }
/** Decorates the remapping function to record statistics if enabled. */ default Function<? super K, ? extends V> statsAware( Function<? super K, ? extends V> mappingFunction, boolean recordLoad) { if (!isRecordingStats()) { return mappingFunction; } return key -> { V value; statsCounter().recordMisses(1); long startTime = statsTicker().read(); try { value = mappingFunction.apply(key); } catch (RuntimeException | Error e) { statsCounter().recordLoadFailure(statsTicker().read() - startTime); throw e; } long loadTime = statsTicker().read() - startTime; if (recordLoad) { if (value == null) { statsCounter().recordLoadFailure(loadTime); } else { statsCounter().recordLoadSuccess(loadTime); } } return value; }; }