LruCache.java revision 9b5a93550f3853b229ae9cfb5f6cf33091478023
1e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson/* 2e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Copyright (C) 2011 The Android Open Source Project 3e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 4e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * you may not use this file except in compliance with the License. 6e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * You may obtain a copy of the License at 7e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 8e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 10e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * See the License for the specific language governing permissions and 14e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * limitations under the License. 15e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 16e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 17e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilsonpackage android.util; 18e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 19e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilsonimport java.util.LinkedHashMap; 20e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilsonimport java.util.Map; 21e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 22e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson/** 23e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * A cache that holds strong references to a limited number of values. Each time 24e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * a value is accessed, it is moved to the head of a queue. When a value is 25e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * added to a full cache, the value at the end of that queue is evicted and may 26e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * become eligible for garbage collection. 27e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 28e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * <p>If your cached values hold resources that need to be explicitly released, 29e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * override {@link #entryEvicted}. This method is only invoked when values are 30e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * evicted. Values replaced by calls to {@link #put} must be released manually. 31e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 32e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * <p>If a cache miss should be computed on demand for the corresponding keys, 33e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * override {@link #create}. This simplifies the calling code, allowing it to 34e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * assume a value will always be returned, even when there's a cache miss. 35e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 36e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * <p>By default, the cache size is measured in the number of entries. Override 3734895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * {@link #sizeOf} to size the cache in different units. For example, this cache 3834895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * is limited to 4MiB of bitmaps: 39e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * <pre> {@code 4034895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * int cacheSize = 4 * 1024 * 1024; // 4MiB 4134895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) { 4234895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * protected int sizeOf(String key, Bitmap value) { 4334895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * return value.getByteCount(); 4434895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * } 4534895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * }}</pre> 4634895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * 4734895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * <p>This class is thread-safe. Perform multiple cache operations atomically by 4834895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * synchronizing on the cache: <pre> {@code 4934895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * synchronized (cache) { 5034895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * if (cache.get(key) == null) { 5134895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * cache.put(key, value); 52e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * } 5334895b09db3679c7d4e80d21198847d316e6b0c3Jesse Wilson * }}</pre> 54e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 55e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilsonpublic class LruCache<K, V> { 56e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private final LinkedHashMap<K, V> map; 57e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 58e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** Size of this cache in units. Not necessarily the number of elements. */ 59e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int size; 609b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson private int maxSize; 61e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 62e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int putCount; 63e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int createCount; 64e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int evictionCount; 65e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int hitCount; 66e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int missCount; 67e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 68e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 69e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * @param maxSize for caches that do not override {@link #sizeOf}, this is 70e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * the maximum number of entries in the cache. For all other caches, 71e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * this is the maximum sum of the sizes of the entries in this cache. 72e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 73e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public LruCache(int maxSize) { 74e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (maxSize <= 0) { 75e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson throw new IllegalArgumentException("maxSize <= 0"); 76e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 77e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson this.maxSize = maxSize; 78e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson this.map = new LinkedHashMap<K, V>(0, 0.75f, true); 79e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 80e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 81e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 82e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the value for {@code key} if it exists in the cache or can be 83e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * created by {@code #create}. If a value was returned, it is moved to the 84e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * head of the queue. This returns null if a value is not cached and cannot 85e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * be created. 86e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 87e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final V get(K key) { 88e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (key == null) { 89e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson throw new NullPointerException(); 90e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 91e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 92e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson V result = map.get(key); 93e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (result != null) { 94e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson hitCount++; 95e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return result; 96e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 97e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 98e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson missCount++; 99e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 100e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson // TODO: release the lock while calling this potentially slow user code 101e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson result = create(key); 102e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 103e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (result != null) { 104e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson createCount++; 105e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson size += safeSizeOf(key, result); 106e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson map.put(key, result); 107e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson trimToSize(maxSize); 108e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 109e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return result; 110e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 111e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 112e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 113e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Caches {@code value} for {@code key}. The value is moved to the head of 114e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * the queue. 115e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 116e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * @return the previous value mapped by {@code key}. Although that entry is 117e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * no longer cached, it has not been passed to {@link #entryEvicted}. 118e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 119e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final V put(K key, V value) { 120e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (key == null || value == null) { 121e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson throw new NullPointerException(); 122e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 123e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 124e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson putCount++; 125e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson size += safeSizeOf(key, value); 126e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson V previous = map.put(key, value); 127e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (previous != null) { 128e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson size -= safeSizeOf(key, previous); 129e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 130e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson trimToSize(maxSize); 131e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return previous; 132e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 133e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 134e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private void trimToSize(int maxSize) { 135e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson while (size > maxSize) { 136e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson Map.Entry<K, V> toEvict = map.eldest(); 137e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (toEvict == null) { 138e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson break; // map is empty; if size is not 0 then throw an error below 139e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 140e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 141e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson K key = toEvict.getKey(); 142e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson V value = toEvict.getValue(); 143e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson map.remove(key); 144e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson size -= safeSizeOf(key, value); 145e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson evictionCount++; 146e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 147e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson // TODO: release the lock while calling this potentially slow user code 148e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson entryEvicted(key, value); 149e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 150e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 151e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (size < 0 || (map.isEmpty() && size != 0)) { 152e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson throw new IllegalStateException(getClass().getName() 153e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson + ".sizeOf() is reporting inconsistent results!"); 154e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 155e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 156e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 157e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 1589b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * Sets the maximum size of this cache. Decreasing the maximum size may 1599b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * evict entries from this cache. 1609b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * 1619b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * @param maxSize for caches that do not override {@link #sizeOf}, this is 1629b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * the maximum number of entries in the cache. For all other caches, 1639b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * this is the maximum sum of the sizes of the entries in this cache. 1649b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson */ 1659b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson public synchronized final void setMaxSize(int maxSize) { 1669b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson if (maxSize <= 0) { 1679b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson throw new IllegalArgumentException("maxSize <= 0"); 1689b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson } 1699b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson 1709b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson trimToSize(maxSize); 1719b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson this.maxSize = maxSize; 1729b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson } 1739b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson 1749b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson /** 175e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Called for entries that have reached the tail of the least recently used 176e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * queue and are be removed. The default implementation does nothing. 177e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 178e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson protected void entryEvicted(K key, V value) {} 179e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 180e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 181e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Called after a cache miss to compute a value for the corresponding key. 182e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the computed value or null if no value can be computed. The 183e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * default implementation returns null. 184e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 185e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson protected V create(K key) { 186e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return null; 187e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 188e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 189e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson private int safeSizeOf(K key, V value) { 190e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson int result = sizeOf(key, value); 191e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson if (result < 0) { 192e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson throw new IllegalStateException("Negative size: " + key + "=" + value); 193e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 194e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return result; 195e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 196e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 197e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 198e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the size of the entry for {@code key} and {@code value} in 199e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * user-defined units. The default implementation returns 1 so that size 200e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * is the number of entries and max size is the maximum number of entries. 201e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * 202e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * <p>An entry's size must not change while it is in the cache. 203e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 204e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson protected int sizeOf(K key, V value) { 205e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return 1; 206e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 207e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 208e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 209e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Clear the cache, calling {@link #entryEvicted} on each removed entry. 210e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 211e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final void evictAll() { 212e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson trimToSize(-1); // -1 will evict 0-sized elements 213e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 214e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 215e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 2169b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * For caches that do not override {@link #sizeOf}, this returns the number 2179b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * of entries in the cache. For all other caches, this returns the sum of 2189b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * the sizes of the entries in this cache. 219e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 220e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final int size() { 221e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return size; 222e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 223e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 224e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 2259b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * For caches that do not override {@link #sizeOf}, this returns the maximum 2269b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * number of entries in the cache. For all other caches, this returns the 2279b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson * maximum sum of the sizes of the entries in this cache. 2289b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson */ 2299b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson public synchronized final int maxSize() { 2309b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson return maxSize; 2319b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson } 2329b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson 2339b5a93550f3853b229ae9cfb5f6cf33091478023Jesse Wilson /** 234e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the number of times {@link #get} returned a value. 235e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 236e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final int hitCount() { 237e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return hitCount; 238e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 239e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 240e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 241e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the number of times {@link #get} returned null or required a new 242e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * value to be created. 243e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 244e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final int missCount() { 245e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return missCount; 246e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 247e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 248e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 249e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the number of times {@link #create(Object)} returned a value. 250e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 251e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final int createCount() { 252e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return createCount; 253e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 254e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 255e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 256e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the number of times {@link #put} was called. 257e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 258e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final int putCount() { 259e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return putCount; 260e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 261e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 262e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 263e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns the number of values that have been evicted. 264e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 265e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final int evictionCount() { 266e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return evictionCount; 267e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 268e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 269e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson /** 270e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * Returns a copy of the current contents of the cache, ordered from least 271e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson * recently accessed to most recently accessed. 272e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson */ 273e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson public synchronized final Map<K, V> snapshot() { 274e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return new LinkedHashMap<K, V>(map); 275e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 276e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson 277e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson @Override public synchronized final String toString() { 278e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson int accesses = hitCount + missCount; 279e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson int hitPercent = accesses != 0 ? (100 * hitCount / accesses) : 0; 280e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson return String.format("LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]", 281e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson maxSize, hitCount, missCount, hitPercent); 282e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson } 283e2c1f4a0ee026e7a2a15d198dc3be4529896e9f6Jesse Wilson} 284