11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 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 static com.google.common.base.Objects.firstNonNull; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkState; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtIncompatible; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Ascii; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalence; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalences; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Objects; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Supplier; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Suppliers; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Ticker; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.AbstractCache.SimpleStatsCounter; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.AbstractCache.StatsCounter; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.Strength; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.ref.SoftReference; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.ref.WeakReference; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.ConcurrentModificationException; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ConcurrentHashMap; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.logging.Level; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.logging.Logger; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.CheckReturnValue; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>A builder of {@link LoadingCache} and {@link Cache} instances having any combination of the 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * following features: 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <ul> 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>automatic loading of entries into the cache 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>least-recently-used eviction when a maximum size is exceeded 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>time-based expiration of entries, measured since last access or last write 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>keys automatically wrapped in {@linkplain WeakReference weak} references 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>values automatically wrapped in {@linkplain WeakReference weak} or 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain SoftReference soft} references 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <li>notification of evicted (or otherwise removed) entries 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * </ul> 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Usage example: <pre> {@code 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * .maximumSize(10000) 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * .expireAfterWrite(10, TimeUnit.MINUTES) 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * .removalListener(MY_LISTENER) 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * .build( 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * new CacheLoader<Key, Graph>() { 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * public Graph load(Key key) throws AnyException { 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * return createExpensiveGraph(key); 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * } 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * });}</pre> 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * These features are all optional. 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned cache is implemented as a hash table with similar performance characteristics to 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link ConcurrentHashMap}. It implements all optional operations of the {@link LoadingCache} and 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Cache} interfaces. The {@code asMap} view (and its collection views) have <i>weakly 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * consistent iterators</i>. This means that they are safe for concurrent use, but if other threads 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modify the cache after the iterator is created, it is undefined which of these changes, if any, 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are reflected in that iterator. These iterators never throw {@link 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * ConcurrentModificationException}. 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> by default, the returned cache uses equality comparisons (the 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Object#equals equals} method) to determine equality for keys or values. However, if 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #weakKeys} was specified, the cache uses identity ({@code ==}) 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * comparisons instead for keys. Likewise, if {@link #weakValues} or {@link #softValues} was 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * specified, the cache uses identity comparisons for values. 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Entries are automatically evicted from the cache when any of 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #maximumSize(long) maximumSize}, {@linkplain #maximumWeight(long) maximumWeight}, 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #expireAfterWrite expireAfterWrite}, 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #expireAfterAccess expireAfterAccess}, {@linkplain #weakKeys weakKeys}, 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #weakValues weakValues}, or {@linkplain #softValues softValues} are requested. 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@linkplain #maximumSize(long) maximumSize} or 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #maximumWeight(long) maximumWeight} is requested entries may be evicted on each cache 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * modification. 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@linkplain #expireAfterWrite expireAfterWrite} or 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #expireAfterAccess expireAfterAccess} is requested entries may be evicted on each 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * cache modification, on occasional cache accesses, or on calls to {@link Cache#cleanUp}. Expired 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entries may be counted in {@link Cache#size}, but will never be visible to read or write 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * operations. 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@linkplain #weakKeys weakKeys}, {@linkplain #weakValues weakValues}, or 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #softValues softValues} are requested, it is possible for a key or value present in 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the cache to be reclaimed by the garbage collector. Entries with reclaimed keys or values may be 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removed from the cache on each cache modification, on occasional cache accesses, or on calls to 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Cache#cleanUp}; such entries may be counted in {@link Cache#size}, but will never be 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * visible to read or write operations. 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Certain cache configurations will result in the accrual of periodic maintenance tasks which 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * will be performed during write operations, or during occasional read operations in the absense of 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * writes. The {@link Cache#cleanUp} method of the returned cache will also perform maintenance, but 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * calling it should not be necessary with a high throughput cache. Only caches built with 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #removalListener removalListener}, {@linkplain #expireAfterWrite expireAfterWrite}, 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #expireAfterAccess expireAfterAccess}, {@linkplain #weakKeys weakKeys}, 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #weakValues weakValues}, or {@linkplain #softValues softValues} perform periodic 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * maintenance. 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The caches produced by {@code CacheBuilder} are serializable, and the deserialized caches 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * retain all the configuration properties of the original cache. Note that the serialized form does 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <i>not</i> include cache contents, but only configuration. 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param <K> the base key type for all caches created by this builder 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param <V> the base value type for all caches created by this builder 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Charles Fry 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true) 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class CacheBuilder<K, V> { 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int DEFAULT_INITIAL_CAPACITY = 16; 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int DEFAULT_CONCURRENCY_LEVEL = 4; 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int DEFAULT_EXPIRATION_NANOS = 0; 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final int DEFAULT_REFRESH_NANOS = 0; 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final Supplier<? extends StatsCounter> NULL_STATS_COUNTER = Suppliers.ofInstance( 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new StatsCounter() { 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordHits(int count) {} 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordMisses(int count) {} 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordLoadSuccess(long loadTime) {} 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordLoadException(long loadTime) {} 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void recordEviction() {} 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheStats snapshot() { 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return EMPTY_STATS; 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }); 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final CacheStats EMPTY_STATS = new CacheStats(0, 0, 0, 0, 0, 0); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final Supplier<SimpleStatsCounter> CACHE_STATS_COUNTER = 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Supplier<SimpleStatsCounter>() { 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public SimpleStatsCounter get() { 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new SimpleStatsCounter(); 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert enum NullListener implements RemovalListener<Object, Object> { 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert INSTANCE; 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void onRemoval(RemovalNotification<Object, Object> notification) {} 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert enum OneWeigher implements Weigher<Object, Object> { 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert INSTANCE; 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int weigh(Object key, Object value) { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 1; 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final Ticker NULL_TICKER = new Ticker() { 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public long read() { 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final Logger logger = Logger.getLogger(CacheBuilder.class.getName()); 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final int UNSET_INT = -1; 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean strictParsing = true; 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int initialCapacity = UNSET_INT; 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int concurrencyLevel = UNSET_INT; 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long maximumSize = UNSET_INT; 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long maximumWeight = UNSET_INT; 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Weigher<? super K, ? super V> weigher; 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Strength keyStrength; 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Strength valueStrength; 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long expireAfterWriteNanos = UNSET_INT; 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long expireAfterAccessNanos = UNSET_INT; 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long refreshNanos = UNSET_INT; 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<Object> keyEquivalence; 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<Object> valueEquivalence; 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<? super K, ? super V> removalListener; 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ticker ticker; 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends StatsCounter> statsCounterSupplier = CACHE_STATS_COUNTER; 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(fry): make constructor private and update tests to use newBuilder 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder() {} 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Constructs a new {@code CacheBuilder} instance with default settings, including strong keys, 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * strong values, and no automatic eviction of any kind. 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static CacheBuilder<Object, Object> newBuilder() { 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CacheBuilder<Object, Object>(); 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Enables lenient parsing. Useful for tests and spec parsing. 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> lenientParsing() { 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert strictParsing = false; 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Sets a custom {@code Equivalence} strategy for comparing keys. 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>By default, the cache uses {@link Equivalences#identity} to determine key equality when 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #weakKeys} is specified, and {@link Equivalences#equals()} otherwise. 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> keyEquivalence(Equivalence<Object> equivalence) { 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(keyEquivalence == null, "key equivalence was already set to %s", keyEquivalence); 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keyEquivalence = checkNotNull(equivalence); 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<Object> getKeyEquivalence() { 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return firstNonNull(keyEquivalence, getKeyStrength().defaultEquivalence()); 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Sets a custom {@code Equivalence} strategy for comparing values. 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>By default, the cache uses {@link Equivalences#identity} to determine value equality when 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #weakValues} or {@link #softValues} is specified, and {@link Equivalences#equals()} 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * otherwise. 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> valueEquivalence(Equivalence<Object> equivalence) { 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(valueEquivalence == null, 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "value equivalence was already set to %s", valueEquivalence); 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.valueEquivalence = checkNotNull(equivalence); 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<Object> getValueEquivalence() { 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return firstNonNull(valueEquivalence, getValueStrength().defaultEquivalence()); 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Sets the minimum total size for the internal hash tables. For example, if the initial capacity 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is {@code 60}, and the concurrency level is {@code 8}, then eight segments are created, each 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * having a hash table of size eight. Providing a large enough estimate at construction time 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * avoids the need for expensive resizing operations later, but setting this value unnecessarily 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * high wastes memory. 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code initialCapacity} is negative 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if an initial capacity was already set 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> initialCapacity(int initialCapacity) { 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.initialCapacity == UNSET_INT, "initial capacity was already set to %s", 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.initialCapacity); 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(initialCapacity >= 0); 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.initialCapacity = initialCapacity; 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int getInitialCapacity() { 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (initialCapacity == UNSET_INT) ? DEFAULT_INITIAL_CAPACITY : initialCapacity; 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * table is internally partitioned to try to permit the indicated number of concurrent updates 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * without contention. Because assignment of entries to these partitions is not necessarily 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * uniform, the actual concurrency observed may vary. Ideally, you should choose a value to 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * accommodate as many threads as will ever concurrently modify the table. Using a significantly 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * higher value than you need can waste space and time, and a significantly lower value can lead 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to thread contention. But overestimates and underestimates within an order of magnitude do not 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * usually have much noticeable impact. A value of one permits only one thread to modify the cache 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * at a time, but since read operations can proceed concurrently, this still yields higher 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * concurrency than full synchronization. Defaults to 4. 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b>The default may change in the future. If you care about this value, you should 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * always choose it explicitly. 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code concurrencyLevel} is nonpositive 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if a concurrency level was already set 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> concurrencyLevel(int concurrencyLevel) { 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.concurrencyLevel == UNSET_INT, "concurrency level was already set to %s", 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.concurrencyLevel); 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(concurrencyLevel > 0); 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.concurrencyLevel = concurrencyLevel; 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int getConcurrencyLevel() { 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (concurrencyLevel == UNSET_INT) ? DEFAULT_CONCURRENCY_LEVEL : concurrencyLevel; 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies the maximum number of entries the cache may contain. Note that the cache <b>may evict 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * an entry before this limit is exceeded</b>. As the cache size grows close to the maximum, the 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * cache evicts entries that are less likely to be used again. For example, the cache may evict an 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * entry because it hasn't been used recently or very often. 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When {@code size} is zero, elements will be evicted immediately after being loaded into the 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * cache. This can be useful in testing, or to disable caching temporarily without a code change. 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param size the maximum size of the cache 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code size} is negative 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if a maximum size was already set 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> maximumSize(long size) { 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s", 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumSize); 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s", 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumWeight); 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.weigher == null, "maximum size can not be combined with weigher"); 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(size >= 0, "maximum size must not be negative"); 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumSize = size; 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies the maximum weight of entries the cache may contain. Weight is determined using the 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link Weigher} specified with {@link #weigher}, and use of this method requires a 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * corresponding call to {@link #weigher} prior to calling {@link #build}. 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that the cache <b>may evict an entry before this limit is exceeded</b>. As the cache 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * size grows close to the maximum, the cache evicts entries that are less likely to be used 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * again. For example, the cache may evict an entry because it hasn't been used recently or very 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * often. 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When {@code weight} is zero, elements will be evicted immediately after being loaded into 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * cache. This can be useful in testing, or to disable caching temporarily without a code 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * change. 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param weight the maximum weight the cache may contain 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code size} is negative 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if a maximum size was already set 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> maximumWeight(long weight) { 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.maximumWeight == UNSET_INT, "maximum weight was already set to %s", 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumWeight); 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.maximumSize == UNSET_INT, "maximum size was already set to %s", 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumSize); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumWeight = weight; 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(weight >= 0, "maximum weight must not be negative"); 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies the weigher to use in determining the weight of entries. Entry weight is taken 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * into consideration by {@link #maximumWeight(long)} when determining which entries to evict, and 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * use of this method requires a corresponding call to {@link #maximumWeight(long)} prior to 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * calling {@link #build}. Weights are measured and recorded when entries are inserted into the 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * cache, and are thus effectively static during the lifetime of a cache entry. 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When the weight of an entry is zero it will not be considered for size-based eviction 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (though it still may be evicted by other means). 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Important note:</b> Instead of returning <em>this</em> as a {@code CacheBuilder} 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * instance, this method returns {@code CacheBuilder<K1, V1>}. From this point on, either the 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * original reference or the returned reference may be used to complete configuration and build 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the cache, but only the "generic" one is type-safe. That is, it will properly prevent you from 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * building caches whose key or value types are incompatible with the types accepted by the 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * weigher already provided; the {@code CacheBuilder} type cannot do this. For best results, 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * simply use the standard method-chaining idiom, as illustrated in the documentation at top, 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * configuring a {@code CacheBuilder} and building your {@link Cache} all in a single statement. 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> if you ignore the above advice, and use this {@code CacheBuilder} to build 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a cache whose key or value type is incompatible with the weigher, you will likely experience 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a {@link ClassCastException} at some <i>undefined</i> point in the future. 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param weigher the weigher to use in calculating the weight of cache entries 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code size} is negative 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if a maximum size was already set 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public <K1 extends K, V1 extends V> CacheBuilder<K1, V1> weigher( 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Weigher<? super K1, ? super V1> weigher) { 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.weigher == null); 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (strictParsing) { 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.maximumSize == UNSET_INT, "weigher can not be combined with maximum size", 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.maximumSize); 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // safely limiting the kinds of caches this can produce 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K1, V1> me = (CacheBuilder<K1, V1>) this; 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert me.weigher = checkNotNull(weigher); 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return me; 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long getMaximumWeight() { 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expireAfterWriteNanos == 0 || expireAfterAccessNanos == 0) { 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (weigher == null) ? maximumSize : maximumWeight; 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Make a safe contravariant cast now so we don't have to do it over and over. 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert <K1 extends K, V1 extends V> Weigher<K1, V1> getWeigher() { 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Weigher<K1, V1>) Objects.firstNonNull(weigher, OneWeigher.INSTANCE); 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each key (not value) stored in the cache should be strongly referenced. 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the key strength was already set 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> strongKeys() { 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return setKeyStrength(Strength.STRONG); 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each key (not value) stored in the cache should be wrapped in a {@link 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WeakReference} (by default, strong references are used). 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> when this method is used, the resulting cache will use identity ({@code ==}) 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * comparison to determine equality of keys. 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Entries with keys that have been garbage collected may be counted in {@link Cache#size}, 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * but will never be visible to read or write operations; such entries are cleaned up as part of 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the routine maintenance described in the class javadoc. 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the key strength was already set 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.lang.ref.WeakReference") 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> weakKeys() { 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return setKeyStrength(Strength.WEAK); 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> setKeyStrength(Strength strength) { 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(keyStrength == null, "Key strength was already set to %s", keyStrength); 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert keyStrength = checkNotNull(strength); 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Strength getKeyStrength() { 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return firstNonNull(keyStrength, Strength.STRONG); 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each value (not key) stored in the cache should be strongly referenced. 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the value strength was already set 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> strongValues() { 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return setValueStrength(Strength.STRONG); 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each value (not key) stored in the cache should be wrapped in a 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link WeakReference} (by default, strong references are used). 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Weak values will be garbage collected once they are weakly reachable. This makes them a poor 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * candidate for caching; consider {@link #softValues} instead. 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> when this method is used, the resulting cache will use identity ({@code ==}) 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * comparison to determine equality of values. 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Entries with values that have been garbage collected may be counted in {@link Cache#size}, 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * but will never be visible to read or write operations; such entries are cleaned up as part of 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the routine maintenance described in the class javadoc. 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the value strength was already set 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.lang.ref.WeakReference") 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> weakValues() { 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return setValueStrength(Strength.WEAK); 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each value (not key) stored in the cache should be wrapped in a 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link SoftReference} (by default, strong references are used). Softly-referenced objects will 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * be garbage-collected in a <i>globally</i> least-recently-used manner, in response to memory 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * demand. 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> in most circumstances it is better to set a per-cache {@linkplain 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #maximumSize(long) maximum size} instead of using soft references. You should only use this 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * method if you are well familiar with the practical consequences of soft references. 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> when this method is used, the resulting cache will use identity ({@code ==}) 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * comparison to determine equality of values. 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Entries with values that have been garbage collected may be counted in {@link Cache#size}, 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * but will never be visible to read or write operations; such entries are cleaned up as part of 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the routine maintenance described in the class javadoc. 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the value strength was already set 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("java.lang.ref.SoftReference") 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> softValues() { 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return setValueStrength(Strength.SOFT); 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> setValueStrength(Strength strength) { 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(valueStrength == null, "Value strength was already set to %s", valueStrength); 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueStrength = checkNotNull(strength); 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Strength getValueStrength() { 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return firstNonNull(valueStrength, Strength.STRONG); 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each entry should be automatically removed from the cache once a fixed duration 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * has elapsed after the entry's creation, or the most recent replacement of its value. 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When {@code duration} is zero, this method hands off to 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #maximumSize(long) maximumSize}{@code (0)}, ignoring any otherwise-specificed maximum 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * size or weight. This can be useful in testing, or to disable caching temporarily without a code 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * change. 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Expired entries may be counted in {@link Cache#size}, but will never be visible to read or 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * write operations. Expired entries are cleaned up as part of the routine maintenance described 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the class javadoc. 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param duration the length of time after an entry is created that it should be automatically 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * removed 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param unit the unit that {@code duration} is expressed in 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code duration} is negative 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the time to live or time to idle was already set 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> expireAfterWrite(long duration, TimeUnit unit) { 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(expireAfterWriteNanos == UNSET_INT, "expireAfterWrite was already set to %s ns", 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expireAfterWriteNanos); 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit); 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.expireAfterWriteNanos = unit.toNanos(duration); 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long getExpireAfterWriteNanos() { 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (expireAfterWriteNanos == UNSET_INT) ? DEFAULT_EXPIRATION_NANOS : expireAfterWriteNanos; 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that each entry should be automatically removed from the cache once a fixed duration 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * has elapsed after the entry's creation, the most recent replacement of its value, or its last 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * access. Access time is reset by all cache read and write operations (including 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Cache.asMap().get(Object)} and {@code Cache.asMap().put(K, V)}), but not by operations 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * on the collection-views of {@link Cache#asMap}. 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>When {@code duration} is zero, this method hands off to 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link #maximumSize(long) maximumSize}{@code (0)}, ignoring any otherwise-specificed maximum 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * size or weight. This can be useful in testing, or to disable caching temporarily without a code 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * change. 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Expired entries may be counted in {@link Cache#size}, but will never be visible to read or 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * write operations. Expired entries are cleaned up as part of the routine maintenance described 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the class javadoc. 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param duration the length of time after an entry is last accessed that it should be 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * automatically removed 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param unit the unit that {@code duration} is expressed in 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code duration} is negative 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the time to idle or time to live was already set 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> expireAfterAccess(long duration, TimeUnit unit) { 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(expireAfterAccessNanos == UNSET_INT, "expireAfterAccess was already set to %s ns", 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expireAfterAccessNanos); 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(duration >= 0, "duration cannot be negative: %s %s", duration, unit); 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.expireAfterAccessNanos = unit.toNanos(duration); 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long getExpireAfterAccessNanos() { 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (expireAfterAccessNanos == UNSET_INT) 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? DEFAULT_EXPIRATION_NANOS : expireAfterAccessNanos; 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies that active entries are eligible for automatic refresh once a fixed duration has 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * elapsed after the entry's creation, or the most recent replacement of its value. The semantics 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * of refreshes are specified in {@link LoadingCache#refresh}, and are performed by calling 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link CacheLoader#reload}. 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>As the default implementation of {@link CacheLoader#reload} is synchronous, it is 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * recommended that users of this method override {@link CacheLoader#reload} with an asynchrnous 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementation; otherwise refreshes will block other cache operations. 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Currently automatic refreshes are performed when the first stale request for an entry 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * occurs. The request triggering refresh will make a blocking call to {@link CacheLoader#reload} 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and immediately return the new value if the returned future is complete, and the old value 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * otherwise. 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> <i>all exceptions thrown during refresh will be logged and then swallowed</i>. 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param duration the length of time after an entry is created that it should be considered 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * stale, and thus eligible for refresh 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param unit the unit that {@code duration} is expressed in 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code duration} is negative 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if the refresh interval was already set 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("To be supported") 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> refreshAfterWrite(long duration, TimeUnit unit) { 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(unit); 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(refreshNanos == UNSET_INT, "refresh was already set to %s ns", refreshNanos); 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(duration > 0, "duration must be positive: %s %s", duration, unit); 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.refreshNanos = unit.toNanos(duration); 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long getRefreshNanos() { 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (refreshNanos == UNSET_INT) ? DEFAULT_REFRESH_NANOS : refreshNanos; 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies a nanosecond-precision time source for use in determining when entries should be 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * expired. By default, {@link System#nanoTime} is used. 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The primary intent of this method is to facilitate testing of caches which have been 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * configured with {@link #expireAfterWrite} or {@link #expireAfterAccess}. 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if a ticker was already set 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("To be supported") 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public CacheBuilder<K, V> ticker(Ticker ticker) { 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.ticker == null); 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.ticker = checkNotNull(ticker); 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ticker getTicker(boolean recordsTime) { 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (ticker != null) { 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ticker; 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return recordsTime ? Ticker.systemTicker() : NULL_TICKER; 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Specifies a listener instance, which all caches built using this {@code CacheBuilder} will 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * notify each time an entry is removed from the cache by any means. 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Each cache built by this {@code CacheBuilder} after this method is called invokes the 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * supplied listener after removing an element for any reason (see removal causes in {@link 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * RemovalCause}). It will invoke the listener as part of the routine maintenance described 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in the class javadoc. 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note:</b> <i>all exceptions thrown by {@code listener} will be logged (using 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@link java.util.logging.Logger})and then swallowed</i>. 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Important note:</b> Instead of returning <em>this</em> as a {@code CacheBuilder} 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * instance, this method returns {@code CacheBuilder<K1, V1>}. From this point on, either the 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * original reference or the returned reference may be used to complete configuration and build 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the cache, but only the "generic" one is type-safe. That is, it will properly prevent you from 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * building caches whose key or value types are incompatible with the types accepted by the 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * listener already provided; the {@code CacheBuilder} type cannot do this. For best results, 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * simply use the standard method-chaining idiom, as illustrated in the documentation at top, 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * configuring a {@code CacheBuilder} and building your {@link Cache} all in a single statement. 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Warning:</b> if you ignore the above advice, and use this {@code CacheBuilder} to build 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a cache whose key or value type is incompatible with the listener, you will likely experience 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a {@link ClassCastException} at some <i>undefined</i> point in the future. 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalStateException if a removal listener was already set 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @CheckReturnValue 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @GwtIncompatible("To be supported") 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public <K1 extends K, V1 extends V> CacheBuilder<K1, V1> removalListener( 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<? super K1, ? super V1> listener) { 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(this.removalListener == null); 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // safely limiting the kinds of caches this can produce 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K1, V1> me = (CacheBuilder<K1, V1>) this; 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert me.removalListener = checkNotNull(listener); 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return me; 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Make a safe contravariant cast now so we don't have to do it over and over. 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert <K1 extends K, V1 extends V> RemovalListener<K1, V1> getRemovalListener() { 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (RemovalListener<K1, V1>) Objects.firstNonNull(removalListener, NullListener.INSTANCE); 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Disable the accumulation of {@link CacheStats} during the operation of the cache. 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<K, V> disableStats() { 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(statsCounterSupplier == CACHE_STATS_COUNTER); 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert statsCounterSupplier = NULL_STATS_COUNTER; 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Supplier<? extends StatsCounter> getStatsCounterSupplier() { 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return statsCounterSupplier; 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Builds a cache, which either returns an already-loaded value for a given key or atomically 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * computes or retrieves it using the supplied {@code CacheLoader}. If another thread is currently 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * loading the value for this key, simply waits for that thread to finish and returns its 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * loaded value. Note that multiple threads can concurrently load values for distinct keys. 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This method does not alter the state of this {@code CacheBuilder} instance, so it can be 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * invoked again to create multiple independent caches. 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param loader the cache loader used to obtain new values 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a cache having the requested features 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public <K1 extends K, V1 extends V> LoadingCache<K1, V1> build( 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheLoader<? super K1, V1> loader) { 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkWeightWithWeigher(); 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LocalCache.LocalLoadingCache<K1, V1>(this, loader); 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Builds a cache which does not automatically load values when keys are requested. 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Consider {@link #build(CacheLoader)} instead, if it is feasible to implement a 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code CacheLoader}. 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This method does not alter the state of this {@code CacheBuilder} instance, so it can be 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * invoked again to create multiple independent caches. 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return a cache having the requested features 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public <K1 extends K, V1 extends V> Cache<K1, V1> build() { 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkWeightWithWeigher(); 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNonLoadingCache(); 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LocalCache.LocalManualCache<K1, V1>(this); 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void checkNonLoadingCache() { 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(refreshNanos == UNSET_INT, "refreshAfterWrite requires a LoadingCache"); 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void checkWeightWithWeigher() { 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (weigher == null) { 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(maximumWeight == UNSET_INT, "maximumWeight requires weigher"); 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (strictParsing) { 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkState(maximumWeight != UNSET_INT, "weigher requires maximumWeight"); 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (maximumWeight == UNSET_INT) { 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert logger.log(Level.WARNING, "ignoring weigher specified without maximumWeight"); 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a string representation for this CacheBuilder instance. The exact form of the returned 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * string is not specified. 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public String toString() { 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Objects.ToStringHelper s = Objects.toStringHelper(this); 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (initialCapacity != UNSET_INT) { 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("initialCapacity", initialCapacity); 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (concurrencyLevel != UNSET_INT) { 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("concurrencyLevel", concurrencyLevel); 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (maximumWeight != UNSET_INT) { 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (weigher == null) { 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("maximumSize", maximumWeight); 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } else { 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("maximumWeight", maximumWeight); 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expireAfterWriteNanos != UNSET_INT) { 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("expireAfterWrite", expireAfterWriteNanos + "ns"); 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expireAfterAccessNanos != UNSET_INT) { 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("expireAfterAccess", expireAfterAccessNanos + "ns"); 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (keyStrength != null) { 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("keyStrength", Ascii.toLowerCase(keyStrength.toString())); 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (valueStrength != null) { 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.add("valueStrength", Ascii.toLowerCase(valueStrength.toString())); 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (keyEquivalence != null) { 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.addValue("keyEquivalence"); 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (valueEquivalence != null) { 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.addValue("valueEquivalence"); 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (removalListener != null) { 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert s.addValue("removalListener"); 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return s.toString(); 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 822