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    }