View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2005 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.services.statistics.detailed.cache;
18  
19  import java.util.Collection;
20  import java.util.HashMap;
21  import java.util.LinkedList;
22  import java.util.Map;
23  import java.util.Set;
24  
25  /**
26   *
27   * This class is a simple, generic FIFO Cache restricted to a certain size.
28   *
29   * @svnLink $Revision: 3880 $;$Date: 2009-08-04 15:17:52 +0200 (Di, 04. Aug 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/detailed_statistics/common/src/main/java/ch/elca/el4j/services/statistics/detailed/cache/LRUCache.java $
30   *
31   * @param <K> Generic type of Key.
32   * @param <E> Generic type of Element.
33   *
34   * @author David Stefan (DST)
35   */
36  public class LRUCache<K, E> {
37  
38  	/**
39  	 * Internal representation of key queue.
40  	 */
41  	private LinkedList<K> m_keyList;
42  	
43  	/**
44  	 * Internal bag for cache elements.
45  	 */
46  	private Map<K, E> m_items;
47  	
48  	/**
49  	 * Maximum size of queue.
50  	 */
51  	private int m_maxCacheSize;
52  
53  	/**
54  	 * Creates a new LRU cache.
55  	 *
56  	 * @param cacheSize
57  	 *            the maximum number of entries that will be kept in this cache.
58  	 */
59  	public LRUCache(int cacheSize) {
60  		this.m_maxCacheSize = cacheSize;
61  		m_keyList = new LinkedList<K>();
62  		m_items = new HashMap<K, E>();
63  	}
64  
65  	/**
66  	 * Put element to cache.
67  	 *
68  	 * @param key
69  	 *            Key of element
70  	 * @param element
71  	 *            Element to add
72  	 */
73  	public synchronized void put(K key, E element) {
74  		// check for size. If cache is full, throw LRU element away
75  		if (m_keyList.size() >= m_maxCacheSize) {
76  			m_items.remove(m_keyList.removeFirst());
77  		}
78  		updateKeyList(key);
79  		m_items.put(key, element);
80  	}
81  
82  	/**
83  	 * Get element out of cache.
84  	 *
85  	 * @param key
86  	 *            Key of the element to get
87  	 * @return Element from cache
88  	 */
89  	public synchronized E get(K key) {
90  		updateKeyList(key);
91  		return m_items.get(key);
92  	}
93  	
94  	/**
95  	 * Get all elements of cache.
96  	 *
97  	 * @return Collection of all cache elements
98  	 */
99  	public synchronized Collection<E> getAll() {
100 		return m_items.values();
101 	}
102 	
103 	/**
104 	 * Get all keys of bag.
105 	 * @return key set of bag
106 	 */
107 	public synchronized Set<K> getKeys() {
108 		return m_items.keySet();
109 	}
110 	
111 
112 	/**
113 	 * Clear the cache.
114 	 */
115 	public synchronized void clear() {
116 		m_keyList.clear();
117 	}
118 	
119 	/**
120 	 * Moves key to last position in keyList when it's written or read, because
121 	 * it is now the most recently used.
122 	 *
123 	 * @param key Key to update in list
124 	 */
125 	private void updateKeyList(K key) {
126 		// remove key in case it was in the list
127 		m_keyList.remove(key);
128 		// append it to the list
129 		m_keyList.add(key);
130 	}
131 	
132 	
133 }
134