11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.cache; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ImmutableMap; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.util.concurrent.UncheckedExecutionException; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.Callable; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentMap; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ExecutionException; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.atomic.AtomicLong; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * This class provides a skeletal implementation of the {@code Cache} interface to minimize the 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * effort required to implement this interface. 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>To implement a cache, the programmer needs only to extend this class and provide an 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementation for the {@link #getIfPresent} method. {@link #getAllPresent} is implemented in 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * terms of {@code getIfPresent}; {@link #invalidateAll(Iterable)} is implemented in terms of 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #invalidate}. The method {@link #cleanUp} is a no-op. All other methods throw an 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link UnsupportedOperationException}. 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Charles Fry 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class AbstractCache<K, V> implements Cache<K, V> { 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** Constructor for use by subclasses. */ 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected AbstractCache() {} 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V get(K key, Callable<? extends V> valueLoader) throws ExecutionException { 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ImmutableMap<K, V> getAllPresent(Iterable<? extends K> keys) { 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<K, V> result = Maps.newLinkedHashMap(); 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (K key : keys) { 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!result.containsKey(key)) { 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.put(key, getIfPresent(key)); 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImmutableMap.copyOf(result); 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void put(K key, V value) { 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void cleanUp() {} 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public long size() { 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void invalidate(Object key) { 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void invalidateAll(Iterable<?> keys) { 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object key : keys) { 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert invalidate(key); 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void invalidateAll() { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheStats stats() { 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ConcurrentMap<K, V> asMap() { 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V getUnchecked(K key) { 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get(key); 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ExecutionException e) { 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UncheckedExecutionException(e.getCause()); 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V apply(K key) { 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return getUnchecked(key); 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Accumulates statistics during the operation of a {@link Cache} for presentation by {@link 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Cache#stats}. This is solely intended for consumption by {@code Cache} implementors. 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public interface StatsCounter { 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Records cache hits. This should be called when a cache request returns a cached value. 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param count the number of hits to record 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordHits(int count); 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Records cache misses. This should be called when a cache request returns a value that was 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * not found in the cache. This method should be called by the loading thread, as well as by 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * threads blocking on the load. Multiple concurrent calls to {@link Cache} lookup methods with 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the same key on an absent value should result in a single call to either 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code recordLoadSuccess} or {@code recordLoadException} and multiple calls to this method, 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * despite all being served by the results of a single load operation. 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param count the number of misses to record 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordMisses(int count); 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Records the successful load of a new entry. This should be called when a cache request 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * causes an entry to be loaded, and the loading completes successfully. In contrast to 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #recordConcurrentMiss}, this method should only be called by the loading thread. 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * value 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordLoadSuccess(long loadTime); 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Records the failed load of a new entry. This should be called when a cache request causes 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * an entry to be loaded, but an exception is thrown while loading the entry. In contrast to 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #recordConcurrentMiss}, this method should only be called by the loading thread. 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * value prior to an exception being thrown 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordLoadException(long loadTime); 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Records the eviction of an entry from the cache. This should only been called when an entry 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is evicted due to the cache's eviction strategy, and not as a result of manual {@linkplain 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Cache#invalidate invalidations}. 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordEviction(); 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a snapshot of this counter's values. Note that this may be an inconsistent view, as 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * it may be interleaved with update operations. 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheStats snapshot(); 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A thread-safe {@link StatsCounter} implementation for use by {@link Cache} implementors. 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Beta 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static class SimpleStatsCounter implements StatsCounter { 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicLong hitCount = new AtomicLong(); 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicLong missCount = new AtomicLong(); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicLong loadSuccessCount = new AtomicLong(); 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicLong loadExceptionCount = new AtomicLong(); 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicLong totalLoadTime = new AtomicLong(); 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final AtomicLong evictionCount = new AtomicLong(); 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordHits(int count) { 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hitCount.addAndGet(count); 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordMisses(int count) { 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert missCount.addAndGet(count); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordLoadSuccess(long loadTime) { 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert loadSuccessCount.incrementAndGet(); 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalLoadTime.addAndGet(loadTime); 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordLoadException(long loadTime) { 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert loadExceptionCount.incrementAndGet(); 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalLoadTime.addAndGet(loadTime); 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordEviction() { 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert evictionCount.incrementAndGet(); 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheStats snapshot() { 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CacheStats( 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hitCount.get(), 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert missCount.get(), 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert loadSuccessCount.get(), 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert loadExceptionCount.get(), 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalLoadTime.get(), 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert evictionCount.get()); 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Increments all counters by the values in {@code other}. 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void incrementBy(StatsCounter other) { 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheStats otherStats = other.snapshot(); 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hitCount.addAndGet(otherStats.hitCount()); 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert missCount.addAndGet(otherStats.missCount()); 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert loadSuccessCount.addAndGet(otherStats.loadSuccessCount()); 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert loadExceptionCount.addAndGet(otherStats.loadExceptionCount()); 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalLoadTime.addAndGet(otherStats.totalLoadTime()); 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert evictionCount.addAndGet(otherStats.evictionCount()); 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 270