1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| package org.jboss.cache.interceptors; |
9 |
| |
10 |
| import org.apache.commons.logging.Log; |
11 |
| import org.apache.commons.logging.LogFactory; |
12 |
| import org.jboss.cache.CacheSPI; |
13 |
| import org.jboss.cache.Fqn; |
14 |
| import org.jboss.cache.InvocationContext; |
15 |
| import org.jboss.cache.Region; |
16 |
| import org.jboss.cache.RegionManager; |
17 |
| import org.jboss.cache.eviction.EvictedEventNode; |
18 |
| import org.jboss.cache.eviction.NodeEventType; |
19 |
| import org.jboss.cache.marshall.MethodCall; |
20 |
| import org.jboss.cache.marshall.MethodDeclarations; |
21 |
| |
22 |
| import java.util.HashMap; |
23 |
| import java.util.Map; |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| |
29 |
| |
30 |
| |
31 |
| |
32 |
| |
33 |
| public class EvictionInterceptor extends Interceptor |
34 |
| { |
35 |
| private static final Log log = LogFactory.getLog(EvictionInterceptor.class); |
36 |
| |
37 |
| protected RegionManager regionManager; |
38 |
| protected Map<Integer, EvictionMethodHandler> evictionMethodHandlers = new HashMap<Integer, EvictionMethodHandler>(); |
39 |
| |
40 |
383
| public EvictionInterceptor()
|
41 |
| { |
42 |
383
| EvictionMethodHandler handler = new GetNodeEvictionMethodHandler();
|
43 |
383
| evictionMethodHandlers.put(MethodDeclarations.getNodeMethodLocal_id, handler);
|
44 |
383
| evictionMethodHandlers.put(MethodDeclarations.getDataMapMethodLocal_id, handler);
|
45 |
| |
46 |
383
| handler = new GetKeyEvictionMethodHandler();
|
47 |
383
| evictionMethodHandlers.put(MethodDeclarations.getKeyValueMethodLocal_id, handler);
|
48 |
| |
49 |
383
| handler = new RemoveNodeEvictionMethodHandler();
|
50 |
383
| evictionMethodHandlers.put(MethodDeclarations.removeNodeMethodLocal_id, handler);
|
51 |
383
| evictionMethodHandlers.put(MethodDeclarations.removeDataMethodLocal_id, handler);
|
52 |
| |
53 |
383
| handler = new RemoveKeyEvictionMethodHandler();
|
54 |
383
| evictionMethodHandlers.put(MethodDeclarations.removeKeyMethodLocal_id, handler);
|
55 |
| |
56 |
383
| handler = new PutDataEvictionMethodHandler();
|
57 |
383
| evictionMethodHandlers.put(MethodDeclarations.putDataMethodLocal_id, handler);
|
58 |
| |
59 |
383
| handler = new PutDataEraseEvictionMethodHandler();
|
60 |
383
| evictionMethodHandlers.put(MethodDeclarations.putDataEraseMethodLocal_id, handler);
|
61 |
| |
62 |
383
| handler = new PutKeyEvictionMethodHandler();
|
63 |
383
| evictionMethodHandlers.put(MethodDeclarations.putKeyValMethodLocal_id, handler);
|
64 |
383
| evictionMethodHandlers.put(MethodDeclarations.putForExternalReadMethodLocal_id, handler);
|
65 |
| |
66 |
383
| handler = new PartialEvictionEvictionMethodHandler();
|
67 |
383
| evictionMethodHandlers.put(MethodDeclarations.evictNodeMethodLocal_id, handler);
|
68 |
383
| evictionMethodHandlers.put(MethodDeclarations.evictVersionedNodeMethodLocal_id, handler);
|
69 |
| } |
70 |
| |
71 |
| |
72 |
| |
73 |
| |
74 |
| |
75 |
| |
76 |
7
| void setRegionManager(RegionManager regionManager)
|
77 |
| { |
78 |
7
| this.regionManager = regionManager;
|
79 |
| } |
80 |
| |
81 |
760
| public void setCache(CacheSPI cache)
|
82 |
| { |
83 |
760
| super.setCache(cache);
|
84 |
760
| this.regionManager = cache.getRegionManager();
|
85 |
| } |
86 |
| |
87 |
2344460
| public Object invoke(InvocationContext ctx) throws Throwable
|
88 |
| { |
89 |
2344460
| MethodCall m = ctx.getMethodCall();
|
90 |
2344460
| Object ret = super.invoke(ctx);
|
91 |
| |
92 |
2344460
| if (log.isTraceEnabled())
|
93 |
| { |
94 |
0
| log.trace("Invoking EvictionInterceptor");
|
95 |
| } |
96 |
| |
97 |
| |
98 |
| |
99 |
2344460
| this.updateNode(m, ret);
|
100 |
| |
101 |
2344460
| if (log.isTraceEnabled())
|
102 |
| { |
103 |
0
| log.trace("Finished invoking EvictionInterceptor");
|
104 |
| } |
105 |
| |
106 |
2344460
| return ret;
|
107 |
| } |
108 |
| |
109 |
2344460
| protected void updateNode(MethodCall m, Object retVal)
|
110 |
| { |
111 |
2344460
| if (log.isTraceEnabled())
|
112 |
| { |
113 |
0
| log.trace("Updating node/element events with no tx");
|
114 |
| } |
115 |
| |
116 |
2344460
| EvictedEventNode event = this.extractEvent(m, retVal);
|
117 |
2344458
| if (event == null)
|
118 |
| { |
119 |
| |
120 |
1338511
| return;
|
121 |
| } |
122 |
| |
123 |
1005949
| this.doEventUpdatesOnRegionManager(event);
|
124 |
| |
125 |
1005905
| if (log.isTraceEnabled())
|
126 |
| { |
127 |
0
| log.trace("Finished updating node");
|
128 |
| } |
129 |
| } |
130 |
| |
131 |
2344460
| protected EvictedEventNode extractEvent(MethodCall m, Object retVal)
|
132 |
| { |
133 |
2344460
| EvictionMethodHandler handler = this.evictionMethodHandlers.get(m.getMethodId());
|
134 |
2344460
| if (handler == null)
|
135 |
| { |
136 |
117330
| return null;
|
137 |
| } |
138 |
| |
139 |
2227130
| return handler.extractEvictedEventNode(m, retVal);
|
140 |
| } |
141 |
| |
142 |
1362449
| protected boolean canIgnoreEvent(Fqn fqn, NodeEventType type)
|
143 |
| { |
144 |
1362619
| Region r = regionManager.getRegion(fqn, Region.Type.EVICTION, false);
|
145 |
0
| if (r == null) return true;
|
146 |
1362619
| return r.getEvictionPolicy().canIgnoreEvent(fqn, type);
|
147 |
| } |
148 |
| |
149 |
1005896
| protected void doEventUpdatesOnRegionManager(EvictedEventNode event)
|
150 |
| { |
151 |
1005949
| Region region = regionManager.getRegion(event.getFqn(), false);
|
152 |
1005949
| region.putNodeEvent(event);
|
153 |
| |
154 |
1005949
| if (log.isTraceEnabled())
|
155 |
| { |
156 |
0
| log.trace("Adding event " + event + " to region at " + region.getFqn());
|
157 |
| } |
158 |
| } |
159 |
| |
160 |
| protected class GetNodeEvictionMethodHandler implements EvictionMethodHandler |
161 |
| { |
162 |
367753
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
163 |
| { |
164 |
367753
| if (retVal == null)
|
165 |
| { |
166 |
13267
| if (log.isTraceEnabled())
|
167 |
| { |
168 |
0
| log.trace("No event added. Node does not exist");
|
169 |
| } |
170 |
| |
171 |
13267
| return null;
|
172 |
| } |
173 |
| |
174 |
354486
| Object args[] = mc.getArgs();
|
175 |
354486
| Fqn fqn = (Fqn) args[0];
|
176 |
| |
177 |
354486
| if (fqn != null && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT))
|
178 |
| { |
179 |
354478
| if (fqn != null
|
180 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT)) |
181 |
| { |
182 |
354478
| return new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT);
|
183 |
| } |
184 |
| } |
185 |
| |
186 |
8
| return null;
|
187 |
| } |
188 |
| } |
189 |
| |
190 |
| protected class GetKeyEvictionMethodHandler implements EvictionMethodHandler |
191 |
| { |
192 |
1467158
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
193 |
| { |
194 |
1467158
| if (retVal == null)
|
195 |
| { |
196 |
1116923
| if (log.isTraceEnabled())
|
197 |
| { |
198 |
0
| log.trace("No event added. Element does not exist");
|
199 |
| } |
200 |
| |
201 |
1116923
| return null;
|
202 |
| } |
203 |
| |
204 |
350235
| Object args[] = mc.getArgs();
|
205 |
350235
| Fqn fqn = (Fqn) args[0];
|
206 |
350235
| Object key = args[1];
|
207 |
350235
| if (fqn != null && key != null
|
208 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT)) |
209 |
| { |
210 |
350235
| return new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT);
|
211 |
| } |
212 |
| |
213 |
0
| return null;
|
214 |
| } |
215 |
| |
216 |
| } |
217 |
| |
218 |
| protected class RemoveNodeEvictionMethodHandler implements EvictionMethodHandler |
219 |
| { |
220 |
16307
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
221 |
| { |
222 |
16307
| Object args[] = mc.getArgs();
|
223 |
16307
| Fqn fqn = (Fqn) args[1];
|
224 |
| |
225 |
16307
| if (fqn != null
|
226 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.REMOVE_NODE_EVENT)) |
227 |
| { |
228 |
16307
| return new EvictedEventNode(fqn, NodeEventType.REMOVE_NODE_EVENT);
|
229 |
| } |
230 |
| |
231 |
0
| return null;
|
232 |
| } |
233 |
| |
234 |
| } |
235 |
| |
236 |
| protected class RemoveKeyEvictionMethodHandler implements EvictionMethodHandler |
237 |
| { |
238 |
4069
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
239 |
| { |
240 |
4069
| if (retVal == null)
|
241 |
| { |
242 |
2001
| if (log.isTraceEnabled())
|
243 |
| { |
244 |
0
| log.trace("No event added. Element does not exist");
|
245 |
| } |
246 |
| |
247 |
2001
| return null;
|
248 |
| } |
249 |
| |
250 |
2068
| Object args[] = mc.getArgs();
|
251 |
2068
| Fqn fqn = (Fqn) args[1];
|
252 |
2068
| Object key = args[2];
|
253 |
2068
| if (fqn != null && key != null
|
254 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.REMOVE_ELEMENT_EVENT)) |
255 |
| { |
256 |
2067
| return new EvictedEventNode(fqn, NodeEventType.REMOVE_ELEMENT_EVENT, 1);
|
257 |
| } |
258 |
1
| return null;
|
259 |
| } |
260 |
| |
261 |
| } |
262 |
| |
263 |
| protected class PutDataEvictionMethodHandler implements EvictionMethodHandler |
264 |
| { |
265 |
9514
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
266 |
| { |
267 |
9514
| Object[] args = mc.getArgs();
|
268 |
9514
| Fqn fqn = (Fqn) args[1];
|
269 |
9514
| Map putData = (Map) args[2];
|
270 |
9514
| if (fqn != null
|
271 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT)) |
272 |
| { |
273 |
9514
| if (putData == null)
|
274 |
| { |
275 |
2184
| if (log.isTraceEnabled())
|
276 |
| { |
277 |
0
| log.trace("Putting null data under fqn " + fqn + ".");
|
278 |
| } |
279 |
| |
280 |
2184
| return null;
|
281 |
| } |
282 |
| |
283 |
7330
| int size;
|
284 |
7330
| synchronized (putData)
|
285 |
| { |
286 |
7330
| size = putData.size();
|
287 |
| } |
288 |
| |
289 |
7330
| return new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, size);
|
290 |
| } |
291 |
| |
292 |
0
| return null;
|
293 |
| } |
294 |
| |
295 |
| } |
296 |
| |
297 |
| protected class PutDataEraseEvictionMethodHandler implements EvictionMethodHandler |
298 |
| { |
299 |
4
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
300 |
| { |
301 |
4
| Object[] args = mc.getArgs();
|
302 |
4
| Fqn fqn = (Fqn) args[1];
|
303 |
4
| Map putData = (Map) args[2];
|
304 |
4
| Boolean resetElementCount = (Boolean) args[4];
|
305 |
4
| if (fqn != null
|
306 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT)) |
307 |
| { |
308 |
4
| if (putData == null)
|
309 |
| { |
310 |
0
| if (log.isTraceEnabled())
|
311 |
| { |
312 |
0
| log.trace("Putting null data under fqn " + fqn + ".");
|
313 |
| } |
314 |
| |
315 |
0
| return null;
|
316 |
| } |
317 |
| |
318 |
4
| int size;
|
319 |
4
| synchronized (putData)
|
320 |
| { |
321 |
4
| size = putData.size();
|
322 |
| } |
323 |
| |
324 |
4
| EvictedEventNode event = new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, size);
|
325 |
4
| event.setResetElementCount(resetElementCount);
|
326 |
4
| return event;
|
327 |
| } |
328 |
| |
329 |
0
| return null;
|
330 |
| } |
331 |
| } |
332 |
| |
333 |
| protected class PutKeyEvictionMethodHandler implements EvictionMethodHandler |
334 |
| { |
335 |
275488
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
336 |
| { |
337 |
275488
| Object[] args = mc.getArgs();
|
338 |
275488
| Fqn fqn = (Fqn) args[1];
|
339 |
275488
| Object key = args[2];
|
340 |
275488
| if (fqn != null && key != null
|
341 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_ELEMENT_EVENT)) |
342 |
| { |
343 |
275487
| return new EvictedEventNode(fqn, NodeEventType.ADD_ELEMENT_EVENT, 1);
|
344 |
| } |
345 |
| |
346 |
1
| return null;
|
347 |
| } |
348 |
| |
349 |
| } |
350 |
| |
351 |
| protected class PartialEvictionEvictionMethodHandler implements EvictionMethodHandler |
352 |
| { |
353 |
86837
| public EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal)
|
354 |
| { |
355 |
| |
356 |
| |
357 |
| |
358 |
| |
359 |
86837
| boolean complete = (retVal != null && (Boolean) retVal);
|
360 |
86837
| if (!complete)
|
361 |
| { |
362 |
41
| Object[] args = mc.getArgs();
|
363 |
41
| Fqn fqn = (Fqn) args[0];
|
364 |
41
| if (fqn != null
|
365 |
| && !EvictionInterceptor.this.canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT)) |
366 |
| { |
367 |
41
| return new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, 0);
|
368 |
| } |
369 |
| } |
370 |
86796
| return null;
|
371 |
| } |
372 |
| } |
373 |
| |
374 |
| protected interface EvictionMethodHandler |
375 |
| { |
376 |
| EvictedEventNode extractEvictedEventNode(MethodCall mc, Object retVal); |
377 |
| } |
378 |
| |
379 |
| } |