Simple Synchronized MRU Cache for Java

Introduction

A very simple and synchronized cache, based on Most Recently Used (MRU) algorithm, written in Java. Cache is based on LinkedHashMap using Generics.

About MRU Cache (wiki)

"When a file is being repeatedly scanned in a Looping Sequential reference pattern, MRU is the best replacement algorithm". In random access patterns and repeated scans over large datasets (sometimes known as cyclic access patterns) MRU cache algorithms have more hits than LRU due to their tendency to retain older data. MRU algorithms are most useful in situations where the older an item is the more likely it is to be accessed

Source Code


import java.util.Map;
import java.util.LinkedHashMap;

/**
* MRU cache based on Linked Hash Map
*
*/
public abstract class MRUCache<K, V> {
   
private final Map<K, V> cache;

   
/**
     *
     *
@param cacheSize cache size
     */
   
public MRUCache ( int cacheSize ) {
       
this .cache = new CacheLinkedHashMap<K, V> ( cacheSize ) ;       
   
}

   
/**
     * Get a value from the cache by a key. if the key is not in the cache the value will be retrieved using the
     * getValue method, then the value will be added to the cache
     *
     *
@param key to look for in the chache
     *
@return value from the cache
     */
   
public V getValueFromCache ( K key ) {
       
V value;
       
synchronized ( this ) {
           
value = cache.get ( key ) ;
       
}
       
if ( value == null ) {
           
value = getValue ( key ) ;
           
synchronized ( this ) {
               
cache.put ( key, value ) ;
           
}
           
return value;
       
}
       
return value;
   
}

   
/**
     *
     *
@param key to get vaue by
     *
@return value to put in the cache
     */
   
protected abstract V getValue ( K key ) ;

   
private static class CacheLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
       
private final int maxSize;

       
public CacheLinkedHashMap ( int maxSize ) {
           
// default load factor is 0.75
           
super ( 0 , 0.75f , true ) ;
           
this .maxSize = maxSize;
       
}

       
protected boolean removeEldestEntry ( Map.Entry eldest ) {
           
return size () > maxSize;
       
}
    }
}

Requirements

  1. Java Platform, Standard Edition 5 and higher (2004)

Usage

Using the MRU cache is easy:

  1. Inherit from the MRUCache class
  2. Set your key and value in your new class
  3. Implement the getValue method
  4. Start using the cache by calling the getValueFromCache method

Example

    public static void main ( String [] args ) {
       
MRUCache<String, String> cache = new MRUCache<String, String> ( 3 ) {
           
protected String getValue ( String key ) {
               
System.out.println ( key ) ;
               
return key;
           
}
        }
;
        cache.getValueFromCache
( "A" ) ;
        cache.getValueFromCache
( "B" ) ;
        cache.getValueFromCache
( "C" ) ;
        cache.getValueFromCache
( "D" ) ; // A will be removed from the cache
       
cache.getValueFromCache ( "B" ) ; // B will be retrieved from the cache
       
cache.getValueFromCache ( "A" ) ; // A will be added to the cache again
   
}

Help and Support

For questions and suggestions please contant support@small-software.com

Ads