159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.terrain.geomipmap; 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Copyright 2007 Christian d'Heureuse, Inventec Informatik AG, Zurich, 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Switzerland 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// www.source-code.biz, www.inventec.ch/chdh 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// This module is multi-licensed and may be used under the terms 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// of any of the following licenses: 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// LGPL, GNU Lesser General Public License, V2 or later, 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// http://www.gnu.org/licenses/lgpl.html 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// GPL, GNU General Public License, V2 or later, 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// http://www.gnu.org/licenses/gpl.html 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// AL, Apache License, V2.0 or later, http://www.apache.org/licenses 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// Please contact the author if you need another license. 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// This module is provided "as is", without warranties of any kind. 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList; 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Collection; 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.LinkedHashMap; 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Map; 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * An LRU cache, based on <code>LinkedHashMap</code>. 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p> 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This cache has a fixed maximum number of elements (<code>cacheSize</code>). 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * If the cache is full and another entry is added, the LRU (least recently 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * used) entry is dropped. 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p> 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class is thread-safe. All methods of this class are synchronized. 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <p> 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br> 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Multi-licensed: EPL / LGPL / GPL / AL / BSD. 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class LRUCache<K, V> { 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private static final float hashTableLoadFactor = 0.75f; 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private LinkedHashMap<K, V> map; 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private int cacheSize; 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Creates a new LRU cache. 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param cacheSize 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the maximum number of entries that will be kept in this cache. 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public LRUCache(int cacheSize) { 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.cacheSize = cacheSize; 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta int hashTableCapacity = (int) Math.ceil(cacheSize / LRUCache.hashTableLoadFactor) + 1; 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.map = new LinkedHashMap<K, V>(hashTableCapacity, LRUCache.hashTableLoadFactor, true) { 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // (an anonymous inner class) 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta private static final long serialVersionUID = 1; 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @Override 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return this.size() > LRUCache.this.cacheSize; 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta }; 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Retrieves an entry from the cache.<br> 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The retrieved entry becomes the MRU (most recently used) entry. 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param key 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the key whose associated value is to be returned. 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the value associated to this key, or null if no value with this 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * key exists in the cache. 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public synchronized V get(K key) { 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return this.map.get(key); 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Adds an entry to this cache. 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The new entry becomes the MRU (most recently used) entry. 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * If an entry with the specified key already exists in the cache, it is 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * replaced by the new entry. 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * If the cache is full, the LRU (least recently used) entry is removed from 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the cache. 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param key 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the key with which the specified value is to be associated. 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param value 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * a value to be associated with the specified key. 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public synchronized void put(K key, V value) { 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.map.put(key, value); 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Clears the cache. 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public synchronized void clear() { 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.map.clear(); 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Returns the number of used entries in the cache. 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the number of entries currently in the cache. 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public synchronized int usedEntries() { 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return this.map.size(); 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Returns a <code>Collection</code> that contains a copy of all cache 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * entries. 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return a <code>Collection</code> with a copy of the cache content. 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public synchronized Collection<Map.Entry<K, V>> getAll() { 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return new ArrayList<Map.Entry<K, V>>(this.map.entrySet()); 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} // end class LRUCache 123