org.rimudb.util.LRUCache2.java Source code

Java tutorial

Introduction

Here is the source code for org.rimudb.util.LRUCache2.java

Source

    /*
     * 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());
        }

    }