1 package com.jme3.terrain.geomipmap; 2 3 // Copyright 2007 Christian d'Heureuse, Inventec Informatik AG, Zurich, 4 // Switzerland 5 // www.source-code.biz, www.inventec.ch/chdh 6 // 7 // This module is multi-licensed and may be used under the terms 8 // of any of the following licenses: 9 // 10 // EPL, Eclipse Public License, V1.0 or later, http://www.eclipse.org/legal 11 // LGPL, GNU Lesser General Public License, V2 or later, 12 // http://www.gnu.org/licenses/lgpl.html 13 // GPL, GNU General Public License, V2 or later, 14 // http://www.gnu.org/licenses/gpl.html 15 // AL, Apache License, V2.0 or later, http://www.apache.org/licenses 16 // BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php 17 // 18 // Please contact the author if you need another license. 19 // This module is provided "as is", without warranties of any kind. 20 import java.util.ArrayList; 21 import java.util.Collection; 22 import java.util.LinkedHashMap; 23 import java.util.Map; 24 25 /** 26 * An LRU cache, based on <code>LinkedHashMap</code>. 27 * 28 * <p> 29 * This cache has a fixed maximum number of elements (<code>cacheSize</code>). 30 * If the cache is full and another entry is added, the LRU (least recently 31 * used) entry is dropped. 32 * 33 * <p> 34 * This class is thread-safe. All methods of this class are synchronized. 35 * 36 * <p> 37 * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br> 38 * Multi-licensed: EPL / LGPL / GPL / AL / BSD. 39 */ 40 public class LRUCache<K, V> { 41 42 private static final float hashTableLoadFactor = 0.75f; 43 private LinkedHashMap<K, V> map; 44 private int cacheSize; 45 46 /** 47 * Creates a new LRU cache. 48 * 49 * @param cacheSize 50 * the maximum number of entries that will be kept in this cache. 51 */ LRUCache(int cacheSize)52 public LRUCache(int cacheSize) { 53 this.cacheSize = cacheSize; 54 int hashTableCapacity = (int) Math.ceil(cacheSize / LRUCache.hashTableLoadFactor) + 1; 55 this.map = new LinkedHashMap<K, V>(hashTableCapacity, LRUCache.hashTableLoadFactor, true) { 56 // (an anonymous inner class) 57 58 private static final long serialVersionUID = 1; 59 60 @Override 61 protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { 62 return this.size() > LRUCache.this.cacheSize; 63 } 64 }; 65 } 66 67 /** 68 * Retrieves an entry from the cache.<br> 69 * The retrieved entry becomes the MRU (most recently used) entry. 70 * 71 * @param key 72 * the key whose associated value is to be returned. 73 * @return the value associated to this key, or null if no value with this 74 * key exists in the cache. 75 */ get(K key)76 public synchronized V get(K key) { 77 return this.map.get(key); 78 } 79 80 /** 81 * Adds an entry to this cache. 82 * The new entry becomes the MRU (most recently used) entry. 83 * If an entry with the specified key already exists in the cache, it is 84 * replaced by the new entry. 85 * If the cache is full, the LRU (least recently used) entry is removed from 86 * the cache. 87 * 88 * @param key 89 * the key with which the specified value is to be associated. 90 * @param value 91 * a value to be associated with the specified key. 92 */ put(K key, V value)93 public synchronized void put(K key, V value) { 94 this.map.put(key, value); 95 } 96 97 /** 98 * Clears the cache. 99 */ clear()100 public synchronized void clear() { 101 this.map.clear(); 102 } 103 104 /** 105 * Returns the number of used entries in the cache. 106 * 107 * @return the number of entries currently in the cache. 108 */ usedEntries()109 public synchronized int usedEntries() { 110 return this.map.size(); 111 } 112 113 /** 114 * Returns a <code>Collection</code> that contains a copy of all cache 115 * entries. 116 * 117 * @return a <code>Collection</code> with a copy of the cache content. 118 */ getAll()119 public synchronized Collection<Map.Entry<K, V>> getAll() { 120 return new ArrayList<Map.Entry<K, V>>(this.map.entrySet()); 121 } 122 } // end class LRUCache 123