KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jodd > cache > AbstractCacheMap


1 // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
2

3 package jodd.cache;
4
5 import java.util.Map JavaDoc;
6
7 /**
8  * Default implementation of timed and size cache map.
9  * Implementations should:
10  * <ul>
11  * <li>create a new cache map
12  * <li>implements own <code>prune</code> strategy
13  * </ul>
14  */

15 public abstract class AbstractCacheMap implements Cache {
16
17     static class CacheObject {
18         CacheObject(Object JavaDoc key, Object JavaDoc object, long timeout) {
19             this.key = key;
20             this.cachedObject = object;
21             this.timeout = timeout;
22             this.lastAccess = System.currentTimeMillis();
23         }
24
25         final Object JavaDoc key;
26         final Object JavaDoc cachedObject;
27         long lastAccess; // time of last access
28
int accessCount; // number of accesses
29
long timeout; // objects timeout, 0 = no timeout
30

31         boolean isExpired() {
32             if (timeout == 0) {
33                 return false;
34             }
35             return lastAccess + timeout < System.currentTimeMillis();
36         }
37         Object JavaDoc getObject() {
38             lastAccess = System.currentTimeMillis();
39             accessCount++;
40             return cachedObject;
41         }
42     }
43
44     protected Map JavaDoc cacheMap;
45
46     // ---------------------------------------------------------------- properties
47

48     protected int cacheSize = 0; // max cache size, 0 = no limit
49

50     /**
51      * Returns cache size or <code>0</code> if there is no size limit.
52      */

53     public int getCacheSize() {
54         return cacheSize;
55     }
56
57     protected long timeout = 0; // default timeout, 0 = no timeout
58

59     /**
60      * Returns default cache timeout or <code>0</code> if it is not set.
61      * Timeout can be set individually for each object.
62      */

63     public long getCacheTimeout() {
64         return timeout;
65     }
66
67     /**
68      * Identifies if objects has custom timeouts.
69      * Should be used to determine if prune for existing objects is needed.
70      */

71     protected boolean existCustomTimeout = false;
72
73     /**
74      * Returns <code>true</code> if prune of expired objects should be invoked.
75      * For internal use.
76      */

77     protected boolean isPruneExpiredActive() {
78         return (timeout != 0) || existCustomTimeout;
79     }
80
81
82     // ---------------------------------------------------------------- put
83

84
85     /**
86      * Adds an object to the cache with default timeout.
87      * @see AbstractCacheMap#put(Object, Object, long)
88      */

89     public synchronized void put(Object JavaDoc key, Object JavaDoc object) {
90         put(key, object, timeout);
91     }
92
93
94     /**
95      * Adds an object to the cache with specified timeout after which it becomes expired.
96      * If cache is full, prune is invoked to make room for new object.
97      */

98     public synchronized void put(Object JavaDoc key, Object JavaDoc object, long timeout) {
99         CacheObject co = new CacheObject(key, object, timeout);
100         if (timeout != 0) {
101             existCustomTimeout = true;
102         }
103         if (isFull()) {
104             prune();
105         }
106         cacheMap.put(key, co);
107     }
108
109
110     // ---------------------------------------------------------------- get
111

112     /**
113      * Retrieves an object from the cache. Returns <code>null</code> if object
114      * is not longer in cache or if it is expired.
115      */

116     public Object JavaDoc get(Object JavaDoc key) {
117         CacheObject co = (CacheObject) cacheMap.get(key);
118         if (co == null) {
119             return null;
120         }
121         if (co.isExpired() == true) {
122             remove(key);
123             return null;
124         }
125         return co.getObject();
126     }
127
128     // ---------------------------------------------------------------- prune
129

130     /**
131      * Prunes objects from cache and returns the number of removed objects.
132      * Which strategy is used depends on cache implementation.
133      */

134     public abstract int prune();
135
136
137     // ---------------------------------------------------------------- common
138

139     /**
140      * Returns <code>true</code> if max cache capacity has been reached
141      * only if cache is size limited.
142      */

143     public boolean isFull() {
144         if (cacheSize == 0) {
145             return false;
146         }
147         return cacheMap.size() >= cacheSize;
148     }
149
150     /**
151      * Removes an object from the cache.
152      */

153     public synchronized void remove(Object JavaDoc key) {
154         cacheMap.remove(key);
155     }
156
157     /**
158      * Clears current cache.
159      */

160     public synchronized void clear() {
161         cacheMap.clear();
162     }
163
164
165     /**
166      * Returns current cache size.
167      */

168     public int size() {
169         return cacheMap.size();
170     }
171 }
172
Popular Tags