Author: sshafroi
Date: 2008-07-14 12:28:27 +0200 (Mon, 14 Jul 2008)
New Revision: 6739
Modified:
trunk/query-api/src/main/java/no/sesat/search/query/parser/AbstractReflectionVisitor.java
Log:
Make the cache for visitor methods thread safe.
Modified:
trunk/query-api/src/main/java/no/sesat/search/query/parser/AbstractReflectionVisitor.java
===================================================================
---
trunk/query-api/src/main/java/no/sesat/search/query/parser/AbstractReflectionVisitor.java
2008-07-14 08:18:45 UTC (rev 6738)
+++
trunk/query-api/src/main/java/no/sesat/search/query/parser/AbstractReflectionVisitor.java
2008-07-14 10:28:27 UTC (rev 6739)
@@ -26,6 +26,10 @@
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.WeakHashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import no.sesat.Interpreter;
import no.sesat.Interpreter.Context;
@@ -73,16 +77,29 @@
/**
* Method implementing Visitor interface. Uses reflection to find the
method with name VISIT_METHOD_IMPL with the
* closest match to the clause subclass.
+ *
+ * We cache the methods used by the visitor in a WeakHashMap. This is done
in a WeakHashMap since the skins can
+ * be reloaded, and then we would have had a memory leak.
+ *
+ * To access the cache we lock using a readlock, and when we need to write
we will lock with a write lock.
+ *
+ * Inside the cache we have another HashMap, this one a thread safe
version, holding the methods.
+ *
* @param clause the clause we're visiting.
*/
- private static WeakHashMap <Class<? extends Visitor>, HashMap<Class<?
extends Clause>, Method>> cache =
- new WeakHashMap<Class<? extends Visitor>,HashMap<Class<? extends
Clause>, Method>>();
-
+ private static WeakHashMap<Class<? extends Visitor>,
ConcurrentHashMap<Class<? extends Clause>, Method>> cache =
+ new WeakHashMap<Class<? extends Visitor>, ConcurrentHashMap<Class<?
extends Clause>, Method>>();
+ private static ReadWriteLock cacheLock = new ReentrantReadWriteLock();
+ private static Lock cacheReadLock = cacheLock.readLock();
public void visit(final Clause clause) {
- HashMap<Class<? extends Clause>, Method> map = cache.get(getClass());
+ cacheReadLock.lock();
+ ConcurrentHashMap<Class<? extends Clause>, Method> map =
cache.get(getClass());
+ cacheReadLock.unlock();
if (map == null) {
- map = new HashMap<Class<? extends Clause>, Method>();
+ map = new ConcurrentHashMap<Class<? extends Clause>, Method>();
+ cacheLock.writeLock().lock();
cache.put(getClass(), map);
+ cacheLock.writeLock().unlock();
}
Method method = map.get(clause.getClass());
if (method == null) {
_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits