1 package org.apache.commons.jcs.engine.memory;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.concurrent.atomic.AtomicLong;
28 import java.util.concurrent.locks.Lock;
29 import java.util.concurrent.locks.ReentrantLock;
30
31 import org.apache.commons.jcs.engine.CacheStatus;
32 import org.apache.commons.jcs.engine.behavior.ICacheElement;
33 import org.apache.commons.jcs.engine.behavior.ICompositeCacheAttributes;
34 import org.apache.commons.jcs.engine.control.CompositeCache;
35 import org.apache.commons.jcs.engine.memory.behavior.IMemoryCache;
36 import org.apache.commons.jcs.engine.memory.util.MemoryElementDescriptor;
37 import org.apache.commons.jcs.engine.stats.StatElement;
38 import org.apache.commons.jcs.engine.stats.Stats;
39 import org.apache.commons.jcs.engine.stats.behavior.IStatElement;
40 import org.apache.commons.jcs.engine.stats.behavior.IStats;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44
45
46
47
48
49
50 public abstract class AbstractMemoryCache<K, V>
51 implements IMemoryCache<K, V>
52 {
53
54 private static final Log log = LogFactory.getLog( AbstractMemoryCache.class );
55
56
57 private ICompositeCacheAttributes cacheAttributes;
58
59
60 private CompositeCache<K, V> cache;
61
62
63 private CacheStatus status;
64
65
66 protected int chunkSize;
67
68 protected final Lock lock = new ReentrantLock();
69
70
71 protected Map<K, MemoryElementDescriptor<K, V>> map;
72
73
74 protected AtomicLong hitCnt;
75
76
77 protected AtomicLong missCnt;
78
79
80 protected AtomicLong putCnt;
81
82
83
84
85
86
87 @Override
88 public void initialize( CompositeCache<K, V> hub )
89 {
90 hitCnt = new AtomicLong(0);
91 missCnt = new AtomicLong(0);
92 putCnt = new AtomicLong(0);
93
94 this.cacheAttributes = hub.getCacheAttributes();
95 this.chunkSize = cacheAttributes.getSpoolChunkSize();
96 this.cache = hub;
97
98 this.map = createMap();
99
100 this.status = CacheStatus.ALIVE;
101 }
102
103
104
105
106
107
108
109 public abstract Map<K, MemoryElementDescriptor<K, V>> createMap();
110
111
112
113
114
115
116
117
118 @Override
119 public abstract boolean remove( K key )
120 throws IOException;
121
122
123
124
125
126
127
128
129 @Override
130 public abstract ICacheElement<K, V> get( K key )
131 throws IOException;
132
133
134
135
136
137
138
139
140
141 @Override
142 public Map<K, ICacheElement<K, V>> getMultiple( Set<K> keys )
143 throws IOException
144 {
145 Map<K, ICacheElement<K, V>> elements = new HashMap<K, ICacheElement<K, V>>();
146
147 if ( keys != null && !keys.isEmpty() )
148 {
149 for (K key : keys)
150 {
151 ICacheElement<K, V> element = get( key );
152
153 if ( element != null )
154 {
155 elements.put( key, element );
156 }
157 }
158 }
159
160 return elements;
161 }
162
163
164
165
166
167
168
169
170
171 @Override
172 public ICacheElement<K, V> getQuiet( K key )
173 throws IOException
174 {
175 ICacheElement<K, V> ce = null;
176
177 MemoryElementDescriptor<K, V> me = map.get( key );
178 if ( me != null )
179 {
180 if ( log.isDebugEnabled() )
181 {
182 log.debug( getCacheName() + ": MemoryCache quiet hit for " + key );
183 }
184
185 ce = me.getCacheElement();
186 }
187 else if ( log.isDebugEnabled() )
188 {
189 log.debug( getCacheName() + ": MemoryCache quiet miss for " + key );
190 }
191
192 return ce;
193 }
194
195
196
197
198
199
200
201 @Override
202 public abstract void update( ICacheElement<K, V> ce )
203 throws IOException;
204
205
206
207
208
209
210 @Override
211 public abstract Set<K> getKeySet();
212
213
214
215
216
217
218 @Override
219 public void removeAll()
220 throws IOException
221 {
222 map.clear();
223 }
224
225
226
227
228
229
230 @Override
231 public void dispose()
232 throws IOException
233 {
234 removeAll();
235 hitCnt.set(0);
236 missCnt.set(0);
237 putCnt.set(0);
238 log.info( "Memory Cache dispose called." );
239 }
240
241
242
243
244 @Override
245 public IStats getStatistics()
246 {
247 IStats stats = new Stats();
248 stats.setTypeName( "Abstract Memory Cache" );
249
250 ArrayList<IStatElement<?>> elems = new ArrayList<IStatElement<?>>();
251 stats.setStatElements(elems);
252
253 elems.add(new StatElement<AtomicLong>("Put Count", putCnt));
254 elems.add(new StatElement<AtomicLong>("Hit Count", hitCnt));
255 elems.add(new StatElement<AtomicLong>("Miss Count", missCnt));
256 elems.add(new StatElement<Integer>( "Map Size", Integer.valueOf(getSize()) ) );
257
258 return stats;
259 }
260
261
262
263
264
265
266 @Override
267 public int getSize()
268 {
269 return this.map.size();
270 }
271
272
273
274
275
276
277 public CacheStatus getStatus()
278 {
279 return this.status;
280 }
281
282
283
284
285
286
287 public String getCacheName()
288 {
289 String attributeCacheName = this.cacheAttributes.getCacheName();
290 if(attributeCacheName != null)
291 {
292 return attributeCacheName;
293 }
294 return cache.getCacheName();
295 }
296
297
298
299
300
301
302 @Override
303 public void waterfal( ICacheElement<K, V> ce )
304 {
305 this.cache.spoolToDisk( ce );
306 }
307
308
309
310
311
312 public void dumpMap()
313 {
314 log.debug( "dumpingMap" );
315 for (Map.Entry<K, MemoryElementDescriptor<K, V>> e : map.entrySet())
316 {
317 MemoryElementDescriptor<K, V> me = e.getValue();
318 log.debug( "dumpMap> key=" + e.getKey() + ", val=" + me.getCacheElement().getVal() );
319 }
320 }
321
322
323
324
325
326
327 @Override
328 public ICompositeCacheAttributes getCacheAttributes()
329 {
330 return this.cacheAttributes;
331 }
332
333
334
335
336
337
338 @Override
339 public void setCacheAttributes( ICompositeCacheAttributes cattr )
340 {
341 this.cacheAttributes = cattr;
342 }
343
344
345
346
347
348
349 @Override
350 public CompositeCache<K, V> getCompositeCache()
351 {
352 return this.cache;
353 }
354 }