Source code: com/opencms/flex/util/CmsLruHashMap.java
1 /*
2 * File : $Source: /usr/local/cvs/opencms/src/com/opencms/flex/util/Attic/CmsLruHashMap.java,v $
3 * Date : $Date: 2003/03/18 01:48:05 $
4 * Version: $Revision: 1.8 $
5 *
6 * This library is part of OpenCms -
7 * the Open Source Content Mananagement System
8 *
9 * Copyright (C) 2002 - 2003 Alkacon Software (http://www.alkacon.com)
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * For further information about Alkacon Software, please see the
22 * company website: http://www.alkacon.com
23 *
24 * For further information about OpenCms, please see the
25 * project website: http://www.opencms.org
26 *
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32 package com.opencms.flex.util;
33
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.Map;
37
38 /**
39 * A hash table based implementation of the Map interface with limited size
40 * and a "last-recently-used" cache policy of the mapped key/values.
41 *
42 * @author Thomas Weckert (t.weckert@alkacon.com)
43 * @version $Revision: 1.8 $
44 * @see CmsFlexLruCache
45 * @see I_CmsFlexLruCacheObject
46 */
47 public class CmsLruHashMap extends HashMap {
48
49 /** LRU cache to organize the cached objects efficient. */
50 private CmsFlexLruCache m_LruCache;
51
52
53 /**
54 * Creates a LRU hash map with an initial capacity of (16), a load factor
55 * of (0.75), and a max. size of cacheable objects of (36).<p>
56 */
57 public CmsLruHashMap() {
58 this( 16, (float)0.75, 36 );
59 }
60
61 /**
62 * Creates a LRU hash map with a given initial capacity, a load factor
63 * of (0.75), and a max. size of cacheable objects of (initialCapacity*3*0.75).<p>
64 *
65 * @param initialCapacity the initial capacity of the hash map
66 */
67 public CmsLruHashMap( int initialCapacity ) {
68 this( initialCapacity, (float)0.75, (int)(initialCapacity*3*0.75) );
69 }
70
71 /**
72 * Creates a LRU hash map with a given initial capacity, a given load factor,
73 * and a max. size of cacheable objects of (initialCapacity*3*loadFactor).<p>
74 *
75 * @param initialCapacity the initial capacity of the hash map
76 * @param loadFactor the load factor of the hash map before it is rehashed
77 */
78 public CmsLruHashMap( int initialCapacity, float loadFactor ) {
79 this( initialCapacity, loadFactor, (int)(initialCapacity*3*loadFactor) );
80 }
81
82 /**
83 * Creates a LRU hash map with a given initial capacity, a load factor of (0.75),
84 * and a given max. size of cacheable objects.<p>
85 *
86 * @param initialCapacity the initial capacity of the hash map
87 * @param maxLruSize the max. count of cacheable objects
88 */
89 public CmsLruHashMap( int initialCapacity, int maxLruSize ) {
90 this( initialCapacity, (float)0.75, maxLruSize );
91 }
92
93 /**
94 * Creates a LRU hash map with a given initial capacity, a given load factor,
95 * and a given max. size of cacheable objects.<p>
96 *
97 * @param initialCapacity the initial capacity of the hash map
98 * @param loadFactor the load factor of the hash map before it is rehashed
99 * @param maxLruSize the max. count of cacheable objects
100 */
101 public CmsLruHashMap( int initialCapacity, float loadFactor, int maxLruSize ) {
102 super( initialCapacity, loadFactor );
103 this.m_LruCache = new CmsFlexLruCache( maxLruSize, (int)(maxLruSize*0.75), -1, false );
104 }
105
106
107 /**
108 * Removes all objects from this map.
109 */
110 public void clear() {
111 this.m_LruCache.clear();
112 super.clear();
113 }
114
115 /**
116 * Clears any allocated resources during finalization.<p>
117 */
118 protected void finalize() throws Throwable {
119 this.clear();
120 this.m_LruCache = null;
121 super.finalize();
122 }
123
124 /**
125 * Returns the value to which the specified key is mapped in this identity
126 * hash map, or null if the map contains no mapping for this key.<p>
127 *
128 * A return
129 * value of null does not necessarily indicate that the map contains no
130 * mapping for the key; it is also possible that the map explicitly maps
131 * the key to null. The containsKey method may be used to distinguish
132 * these two cases.
133 *
134 * @param key the key to look up
135 * @see java.util.Map#get(java.lang.Object)
136 */
137 public Object get( Object key ) {
138 CmsLruCacheObject cachedObject = (CmsLruCacheObject)super.get( key );
139
140 if (cachedObject!=null) {
141 this.m_LruCache.touch( cachedObject );
142 return (Object)cachedObject.getValue();
143 }
144
145 return null;
146 }
147
148 /**
149 * Associates the specified value with the specified key in this map.<p>
150 *
151 * If the map previously contained a mapping for this key, the old value is
152 * replaced.
153 *
154 * @param key the key to store
155 * @param value the value to store
156 *
157 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
158 */
159 public Object put( Object key, Object value ) {
160 CmsLruCacheObject cachedObject = new CmsLruCacheObject( value, key, this );
161
162 if (this.m_LruCache.add(cachedObject)) {
163 CmsLruCacheObject previousMapping = (CmsLruCacheObject)super.put( key, (CmsLruCacheObject)cachedObject );
164
165 if (previousMapping!=null) {
166 return (Object)previousMapping.getValue();
167 }
168 }
169
170 return null;
171 }
172
173 /**
174 * Copies all of the mappings from the specified map to this map.<p>
175 *
176 * These mappings will replace any mappings that this map had for any of the
177 * keys currently in the specified map.
178 *
179 * @param t the map to store
180 *
181 * @see java.util.Map#putAll(java.util.Map)
182 */
183 public void putAll( Map t ) {
184 Iterator allKeys = t.keySet().iterator();
185
186 while (allKeys.hasNext()) {
187 String nextKey = (String)allKeys.next();
188 this.put( nextKey, t.get(nextKey) );
189 }
190
191 }
192
193 /**
194 * Removes the mapping for this key from this map if present.<p>
195 *
196 * @param key the key to remove
197 *
198 * @see java.util.Map#remove(java.lang.Object)
199 */
200 public Object remove( Object key ) {
201 CmsLruCacheObject cachedObject = (CmsLruCacheObject)super.remove( key );
202
203 if (cachedObject!=null) {
204 this.m_LruCache.remove( cachedObject );
205 return (Object)cachedObject.getValue();
206 }
207
208 return null;
209 }
210
211 /**
212 * Returns the internal cache used for the LRU policy.<p>
213 *
214 * @return the internal cache used for the LRU policy
215 */
216 public CmsFlexLruCache getLruCache() {
217 return this.m_LruCache;
218 }
219
220
221 /**
222 * An object saved under the LRU policy in a CmsLruHashMap.<p>
223 *
224 *
225 * @see CmsFlexLruCache
226 * @see I_CmsFlexLruCacheObject
227 * @see CmsLruHashMap
228 */
229 class CmsLruCacheObject extends Object implements I_CmsFlexLruCacheObject {
230
231 private CmsLruHashMap m_ParentHashMap;
232 private Object m_ParentKey;
233 private Object m_Value;
234
235 /** Pointer to the next cache entry in the LRU cache. */
236 private I_CmsFlexLruCacheObject m_Next;
237
238 /** Pointer to the previous cache entry in the LRU cache. */
239 private I_CmsFlexLruCacheObject m_Previous;
240
241 /**
242 * Constuctor.<p>
243 *
244 * @param theInitialValue the initial value
245 * @param theParentKey the parent key
246 * @param theParentHashMap the parent cache
247 */
248 public CmsLruCacheObject( Object theInitialValue, Object theParentKey, CmsLruHashMap theParentHashMap ) {
249 this.m_Next = this.m_Previous = null;
250 this.m_Value = theInitialValue;
251 this.m_ParentKey = theParentKey;
252 this.m_ParentHashMap = theParentHashMap;
253 }
254
255 /**
256 * @see java.lang.Object#finalize()
257 */
258 protected void finalize() throws Throwable {
259 this.m_Next = this.m_Previous = null;
260 this.m_Value = null;
261 this.m_ParentKey = null;
262 this.m_ParentHashMap = null;
263 }
264
265 /**
266 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#setNextLruObject(com.opencms.flex.util.I_CmsFlexLruCacheObject)
267 */
268 public void setNextLruObject( I_CmsFlexLruCacheObject theNextObject ) {
269 this.m_Next = theNextObject;
270 }
271
272 /**
273 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#getNextLruObject()
274 */
275 public I_CmsFlexLruCacheObject getNextLruObject() {
276 return this.m_Next;
277 }
278
279 /**
280 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#setPreviousLruObject(com.opencms.flex.util.I_CmsFlexLruCacheObject)
281 */
282 public void setPreviousLruObject( I_CmsFlexLruCacheObject thePreviousObject ) {
283 this.m_Previous = thePreviousObject;
284 }
285
286 /**
287 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#getPreviousLruObject()
288 */
289 public I_CmsFlexLruCacheObject getPreviousLruObject() {
290 return this.m_Previous;
291 }
292
293 /**
294 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#addToLruCache()
295 */
296 public void addToLruCache() {
297 // NOOP
298 }
299
300 /**
301 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#removeFromLruCache()
302 */
303 public void removeFromLruCache() {
304 this.m_ParentHashMap.remove( this.m_ParentKey );
305 }
306
307 /**
308 * @see com.opencms.flex.util.I_CmsFlexLruCacheObject#getLruCacheCosts()
309 */
310 public int getLruCacheCosts() {
311 return 1;
312 }
313
314 /**
315 * Returns the value.<p>
316 *
317 * @return the value
318 */
319 public Object getValue() {
320 return m_Value;
321 }
322
323 /**
324 * Sets the value.<p>
325 *
326 * @param value the value to set
327 */
328 public void setValue(Object value) {
329 m_Value = value;
330 }
331
332 }
333 }