Mega Code Archive

 
Categories / Java / Development Class
 

LRU Cache 2

/*  * Copyright (c) 2008-2011 Simon Ritchie.  * All rights reserved.   *   * This program is free software: you can redistribute it and/or modify   * it under the terms of the GNU Lesser General Public License as published   * by the Free Software Foundation, either version 3 of the License, or   * (at your option) any later version.  *   * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    * See the GNU Lesser General Public License for more details.  *   * You should have received a copy of the GNU Lesser General Public License   * along with this program.  If not, see http://www.gnu.org/licenses/>.  */ //package org.rimudb.util; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class LRUCache2<K, V> {   private static final float hashTableLoadFactor = 0.75f;   private LinkedHashMap<K, V> map;   private int cacheSize;   /**    * Creates a new LRU cache.    *     * @param cacheSize The maximum number of entries that will be kept in this cache.    */   public LRUCache2(int cacheSize) {     this.cacheSize = cacheSize;     int hashTableCapacity = (int) Math.ceil(cacheSize / hashTableLoadFactor) + 1;          map = new LinkedHashMap<K, V>(hashTableCapacity, hashTableLoadFactor, true) {       private static final long serialVersionUID = 1;       @Override       protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {         return size() > LRUCache2.this.cacheSize;       }     };   }   /**    * Retrieves an entry from the cache.<br>    * The retrieved entry is move to the head of the list as it    * is the most recently used.    *     * @param key    * @return The value associated to this key    */   public synchronized V get(K key) {     return map.get(key);   }   /**    * Adds an entry to this cache. If the cache is full, the LRU (least    * recently used) entry is dropped.    *     * @param key    * @param value    */   public synchronized void put(K key, V value) {     map.put(key, value);   }   /**    * Remove an entry from the cache.    *     * @param key    */   public synchronized void remove(K key) {     map.remove(key);   }   /**    * Clears the cache.    */   public synchronized void clear() {     map.clear();   }   /**    * Returns the number of used entries in the cache.    *     * @return the number of entries currently in the cache.    */   public synchronized int usedEntries() {     return map.size();   }   /**    * Returns a <code>Collection</code> that contains a copy of all cache    * entries.    *     * @return a <code>Collection</code> with a copy of the cache content.    */   public synchronized Collection<Map.Entry<K, V>> getAll() {     return new ArrayList<Map.Entry<K, V>>(map.entrySet());   }   public synchronized Set<K> keySet() {     return map.keySet();   }   public int getMaximumSize() {     return cacheSize;   } } ---------------- /*  * Copyright (c) 2008-2011 Simon Ritchie.  * All rights reserved.   *   * This program is free software: you can redistribute it and/or modify   * it under the terms of the GNU Lesser General Public License as published   * by the Free Software Foundation, either version 3 of the License, or   * (at your option) any later version.  *   * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    * See the GNU Lesser General Public License for more details.  *   * You should have received a copy of the GNU Lesser General Public License   * along with this program.  If not, see http://www.gnu.org/licenses/>.  */ package org.rimudb.util; import java.util.*; import java.util.Map.*; import junit.framework.*; public class LRUCache2Tests extends TestCase {   private LRUCache2<String, String> cache = null;   public LRUCache2Tests(String name) {     super(name);   }   protected void setUp() throws Exception {     cache = new LRUCache2<String, String>(5);   }   protected void tearDown() throws Exception {     super.tearDown();   }   public void testGet() {     cache.put("key1", "value1");     cache.put("key2", "value2");     cache.put("key3", "value3");     cache.put("key4", "value4");     cache.put("key5", "value5");     cache.put("key6", "value6");          assertNull(cache.get("key1"));     assertEquals("value2", cache.get("key2"));     assertEquals("value3", cache.get("key3"));     assertEquals("value4", cache.get("key4"));     assertEquals("value5", cache.get("key5"));     assertEquals("value6", cache.get("key6"));   }   public void testRemove() {     cache.put("key1", "value1");     cache.put("key2", "value2");     cache.put("key3", "value3");     cache.put("key4", "value4");     cache.put("key5", "value5");          assertEquals(5, cache.usedEntries());     cache.remove("key3");     assertEquals(4, cache.usedEntries());   }   public void testClear() {     cache.put("key1", "value1");     cache.put("key2", "value2");     cache.put("key3", "value3");     cache.put("key4", "value4");     cache.put("key5", "value5");          assertEquals(5, cache.usedEntries());     cache.clear();     assertEquals(0, cache.usedEntries());   }   public void testUsedEntries() {     cache.put("key1", "value1");     cache.put("key2", "value2");     assertEquals(2, cache.usedEntries());     cache.put("key3", "value3");     assertEquals(3, cache.usedEntries());     cache.put("key4", "value4");     cache.put("key5", "value5");     assertEquals(5, cache.usedEntries());     cache.put("key6", "value6");     assertEquals(5, cache.usedEntries());     cache.put("key7", "value7");     assertEquals(5, cache.usedEntries());   }   public void testGetAll() {     cache.put("key1", "value1");     cache.put("key2", "value2");     cache.put("key3", "value3");     cache.put("key4", "value4");     cache.put("key5", "value5");     Collection<Entry<String, String>> cacheCopy = cache.getAll();     assertEquals(5, cacheCopy.size());   }   public void testKeySet() {     cache.put("key1", "value1");     cache.put("key2", "value2");     cache.put("key3", "value3");     cache.put("key4", "value4");     cache.put("key5", "value5");     Set<String> keyset = cache.keySet();     assertTrue(keyset.contains("key1"));     assertTrue(keyset.contains("key2"));     assertTrue(keyset.contains("key3"));     assertTrue(keyset.contains("key4"));     assertTrue(keyset.contains("key5"));   }   public void testGetMaximumSize() {     assertEquals(5, cache.getMaximumSize());     cache.put("key1", "value1");     cache.put("key2", "value2");     cache.put("key3", "value3");     cache.put("key4", "value4");     cache.put("key5", "value5");     assertEquals(5, cache.getMaximumSize());   } }