1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.mms.util; 18 19 import java.lang.ref.SoftReference; 20 import java.util.LinkedHashMap; 21 import java.util.Map; 22 23 /** 24 * A simple cache with the option of using {@link SoftReference SoftReferences} to play well with 25 * the garbage collector and an LRU cache eviction algorithm to limit the number 26 * of {@link SoftReference SoftReferences}. 27 * <p> 28 * The interface of this class is a subset of {@link Map}. 29 * 30 * from Peter Balwin and books app. 31 */ 32 public class SimpleCache<K, V> { 33 34 /** 35 * A simple LRU cache to prevent the number of {@link Map.Entry} instances 36 * from growing infinitely. 37 */ 38 @SuppressWarnings("serial") 39 private class SoftReferenceMap extends LinkedHashMap<K, SoftReference<V>> { 40 41 private final int mMaxCapacity; 42 43 public SoftReferenceMap(int initialCapacity, int maxCapacity, float loadFactor) { 44 super(initialCapacity, loadFactor, true); 45 mMaxCapacity = maxCapacity; 46 } 47 48 @Override 49 protected boolean removeEldestEntry(Map.Entry<K, SoftReference<V>> eldest) { 50 return size() > mMaxCapacity; 51 } 52 } 53 54 @SuppressWarnings("serial") 55 private class HardReferenceMap extends LinkedHashMap<K, V> { 56 57 private final int mMaxCapacity; 58 59 public HardReferenceMap(int initialCapacity, int maxCapacity, float loadFactor) { 60 super(initialCapacity, loadFactor, true); 61 mMaxCapacity = maxCapacity; 62 } 63 64 @Override 65 protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { 66 return size() > mMaxCapacity; 67 } 68 } 69 70 private static <V> V unwrap(SoftReference<V> ref) { 71 return ref != null ? ref.get() : null; 72 } 73 74 private final SoftReferenceMap mSoftReferences; 75 private final HardReferenceMap mHardReferences; 76 77 /** 78 * Constructor. 79 * 80 * @param initialCapacity the initial capacity for the cache. 81 * @param maxCapacity the maximum capacity for the 82 * cache (this value may be large if soft references are used because 83 * {@link SoftReference SoftReferences} don't consume much memory compared to the 84 * larger data they typically contain). 85 * @param loadFactor the initial load balancing factor for the internal 86 * {@link LinkedHashMap} 87 */ 88 public SimpleCache(int initialCapacity, int maxCapacity, float loadFactor, 89 boolean useHardReferences) { 90 if (useHardReferences) { 91 mSoftReferences = null; 92 mHardReferences = new HardReferenceMap(initialCapacity, maxCapacity, loadFactor); 93 } else { 94 mSoftReferences = new SoftReferenceMap(initialCapacity, maxCapacity, loadFactor); 95 mHardReferences = null; 96 } 97 } 98 99 /** 100 * See {@link Map#get(Object)}. 101 */ 102 public V get(Object key) { 103 return mSoftReferences != null ? unwrap(mSoftReferences.get(key)) 104 : mHardReferences.get(key); 105 } 106 107 /** 108 * See {@link Map#put(Object, Object)}. 109 */ 110 public V put(K key, V value) { 111 return mSoftReferences != null ? 112 unwrap(mSoftReferences.put(key, new SoftReference<V>(value))) 113 : mHardReferences.put(key, value); 114 } 115 116 /** 117 * See {@link Map#clear()}. 118 */ 119 public void clear() { 120 if (mSoftReferences != null) { 121 mSoftReferences.clear(); 122 } else { 123 mHardReferences.clear(); 124 } 125 } 126 127 /** 128 * See {@link Map#remove(Object)}. 129 */ 130 public V remove(K key) { 131 if (mSoftReferences != null) { 132 return unwrap(mSoftReferences.remove(key)); 133 } else { 134 return mHardReferences.remove(key); 135 } 136 } 137 138 } 139