001 package com.khubla.pragmatach.framework.cache;
002
003 import java.util.ArrayList;
004 import java.util.Collection;
005 import java.util.LinkedHashMap;
006 import java.util.Map;
007
008 /**
009 * A simple LRU cache, based on multiple examples from "The Google".
010 *
011 * @author tome
012 */
013 public class LRUCache<K, V> {
014 /**
015 * load factor
016 */
017 private static final float hashTableLoadFactor = 0.75f;
018 /**
019 * map of entries
020 */
021 private LinkedHashMap<K, V> map;
022 /**
023 * the cache size
024 */
025 private int cacheSize;
026 /**
027 * total requests
028 */
029 private long totalRequests = 0;
030 /**
031 * total hits
032 */
033 private long totalHits = 0;
034
035 /**
036 * ctor
037 */
038 public LRUCache(int cacheSize) {
039 this.cacheSize = cacheSize;
040 final int hashTableCapacity = (int) Math.ceil(cacheSize
041 / hashTableLoadFactor) + 1;
042 map = new LinkedHashMap<K, V>(hashTableCapacity, hashTableLoadFactor,
043 true) {
044 private static final long serialVersionUID = 1;
045
046 @Override
047 protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
048 return map.size() > LRUCache.this.cacheSize;
049 }
050 };
051 }
052
053 public synchronized void clear() {
054 this.totalHits = 0;
055 this.totalRequests = 0;
056 map.clear();
057 }
058
059 public synchronized V get(K key) {
060 final V v = map.get(key);
061 this.totalRequests++;
062 if (null != v) {
063 this.totalHits++;
064 }
065 return v;
066 }
067
068 public synchronized Collection<Map.Entry<K, V>> getAll() {
069 return new ArrayList<Map.Entry<K, V>>(map.entrySet());
070 }
071
072 public long getTotalHits() {
073 return totalHits;
074 }
075
076 public long getTotalRequests() {
077 return totalRequests;
078 }
079
080 public synchronized void put(K key, V value) {
081 map.put(key, value);
082 }
083
084 public synchronized int size() {
085 return map.size();
086 }
087 }