Tuesday, May 8, 2012

Writing own cache in JAVA

Cache is being increasingly used for improving performance. The cache improves the performance by not getting to go to database or any other system which doesnot reside in the memory( here its JVM) again and again. The cache should store those frequently accessed data or objects in the memory itself. Here in this blog i have come up with 4 different kinds of algorithms that you can use to create a cache and store the objects in the memory. In the last part i have combined all these to form the framework which one can use in any java application.

First one is  LRU (Least Recently Used)

It says that the objects that are recently used are the one that will be kept in the cache otherwise it will be removed from the cache.

The code is shown below:

public class LRUCache  {
  private int cacheSize;
  private Map<Object,Object> cache;
  private List<Object> keyList;
  /**
   * Default constructor
   */
  public LRUCache() {
    this.cacheSize = 100;
    this.cache = new ConcurrentHashMap<Object,Object>();
    this.keyList = Collections.synchronizedList(new LinkedList<Object>());
  }
 
  /**
   * Add an object to the cache
   *
   *
   * @param key        The key of the object to be cached
   * @param value      The object to be cached
   */
  public void putObject(Object key, Object value) {
    cache.put(key, value);
    keyList.add(key);
    if (keyList.size() > cacheSize) {
      try {
        Object oldestKey = keyList.remove(0);
        cache.remove(oldestKey);
      } catch (IndexOutOfBoundsException e) {
        //ignore
      }
    }
  }
  /**
   * Get an object out of the cache.
   *
   * @param key        The key of the object to be returned
   * @return The cached object (or null)
   */
  public Object getObject(Object key) {
    Object result = cache.get(key);
    keyList.remove(key);
    if (result != null) {
      keyList.add(key);
    }
    return result;
  }
  public Object removeObject(Object key) {
    keyList.remove(key);
    return cache.remove(key);
  }
  /**
   * Flushes the cache.
   *
   *
   */
  public void flush() {
    cache.clear();
    keyList.clear();
  }
}

The second one is FIFO (First In First Out)

The code for the same algorithm is

public class FifoCache {
  private int cacheSize;
  private Map<Object,Object> cache;
  private List<Object> keyList;
  /**
   * Default constructor
   */
  public FifoCache() {
    this.cacheSize = 100;
    this.cache = new ConcurrentHashMap<Object,Object>();
    this.keyList = Collections.synchronizedList(new LinkedList<Object>());
  }

  /**
   * Add an object to the cache
   *
   *
   * @param key        The key of the object to be cached
   * @param value      The object to be cached
   */
  public void putObject(Object key, Object value) {
    cache.put(key, value);
    keyList.add(key);
    if (keyList.size() > cacheSize) {
      try {
        Object oldestKey = keyList.remove(0);
        cache.remove(oldestKey);
      } catch (IndexOutOfBoundsException e) {
        //ignore
      }
    }
  }
  /**
   * Get an object out of the cache.
   * @param key        The key of the object to be returned
   * @return The cached object (or null)
   */
  public Object getObject(Object key) {
    return cache.get(key);
  }
  public Object removeObject(Object key) {
    keyList.remove(key);
    return cache.remove(key);
  }
  /**
   * Flushes the cache.
   *
   * @param cacheModel The cache model
   */
  public void flush() {
    cache.clear();
    keyList.clear();
  }
}