1package com.bumptech.glide.util; 2 3import java.util.LinkedHashMap; 4import java.util.Map; 5 6/** 7 * A general purpose size limited cache that evicts items using an LRU algorithm. By default every item is assumed to 8 * have a size of one. Subclasses can override {@link #getSize(Object)}} to change the size on a per item basis. 9 * 10 * @param <T> The type of the keys. 11 * @param <Y> The type of the values. 12 */ 13public class LruCache<T, Y> { 14 private final LinkedHashMap<T, Y> cache = new LinkedHashMap<T, Y>(100, 0.75f, true); 15 private int maxSize; 16 private final int initialMaxSize; 17 private int currentSize = 0; 18 19 public LruCache(int size) { 20 this.initialMaxSize = size; 21 this.maxSize = size; 22 } 23 24 public void setSizeMultiplier(float multiplier) { 25 if (multiplier < 0) { 26 throw new IllegalArgumentException("Multiplier must be >= 0"); 27 } 28 maxSize = Math.round(initialMaxSize * multiplier); 29 evict(); 30 } 31 32 protected int getSize(Y item) { 33 return 1; 34 } 35 36 protected void onItemRemoved(T key, Y item) { } 37 38 public int getCurrentSize() { 39 return currentSize; 40 } 41 42 public boolean contains(T key) { 43 return cache.containsKey(key); 44 } 45 46 public Y get(T key) { 47 return cache.get(key); 48 } 49 50 public Y put(T key, Y item) { 51 final int itemSize = getSize(item); 52 if (itemSize >= maxSize) { 53 onItemRemoved(key, item); 54 return null; 55 } 56 57 final Y result = cache.put(key, item); 58 if (result != item) { 59 currentSize += getSize(item); 60 evict(); 61 } 62 return result; 63 } 64 65 public Y remove(T key) { 66 final Y value = cache.remove(key); 67 if (value != null) { 68 currentSize -= getSize(value); 69 } 70 return value; 71 } 72 73 public void clearMemory() { 74 trimToSize(0); 75 } 76 77 protected void trimToSize(int size) { 78 Map.Entry<T, Y> last; 79 while (currentSize > size) { 80 last = cache.entrySet().iterator().next(); 81 final Y toRemove = last.getValue(); 82 currentSize -= getSize(toRemove); 83 final T key = last.getKey(); 84 cache.remove(key); 85 onItemRemoved(key, toRemove); 86 } 87 } 88 89 private void evict() { 90 trimToSize(maxSize); 91 } 92} 93