Repository: cayenne
Updated Branches:
  refs/heads/master 5e9f0e0f6 -> 67225b387


New implementation of MapQueryCache plus new method in QueryCache
 interface for type-safe deletion of cache groups.


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/67225b38
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/67225b38
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/67225b38

Branch: refs/heads/master
Commit: 67225b387a3e5e92a8f81a5059bdd9d27a6c0ac8
Parents: 5e9f0e0
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Mon Apr 3 15:17:57 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Mon Apr 3 15:17:57 2017 +0300

----------------------------------------------------------------------
 .../apache/cayenne/jcache/JCacheQueryCache.java |   8 ++
 .../apache/cayenne/cache/EhCacheQueryCache.java |   4 +
 .../org/apache/cayenne/cache/MapQueryCache.java | 116 ++++++++++++-------
 .../apache/cayenne/cache/NestedQueryCache.java  |   5 +
 .../org/apache/cayenne/cache/OSQueryCache.java  |   4 +
 .../org/apache/cayenne/cache/QueryCache.java    |   9 ++
 .../apache/cayenne/cache/MockQueryCache.java    |   4 +
 7 files changed, 108 insertions(+), 42 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-jcache/src/main/java/org/apache/cayenne/jcache/JCacheQueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-jcache/src/main/java/org/apache/cayenne/jcache/JCacheQueryCache.java 
b/cayenne-jcache/src/main/java/org/apache/cayenne/jcache/JCacheQueryCache.java
index d10a83c..a91efc4 100644
--- 
a/cayenne-jcache/src/main/java/org/apache/cayenne/jcache/JCacheQueryCache.java
+++ 
b/cayenne-jcache/src/main/java/org/apache/cayenne/jcache/JCacheQueryCache.java
@@ -92,6 +92,14 @@ public class JCacheQueryCache implements QueryCache {
     }
 
     @Override
+    public void removeGroup(String groupKey, Class<?> keyType, Class<?> 
valueType) {
+        Cache cache = cacheManager.getCache(groupKey, keyType, valueType);
+        if (cache != null) {
+            cache.clear();
+        }
+    }
+
+    @Override
     public void clear() {
         for (String name : seenCacheNames) {
             getCache(name).clear();

http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-server/src/main/java/org/apache/cayenne/cache/EhCacheQueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/EhCacheQueryCache.java 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/EhCacheQueryCache.java
index 454e5fe..a3137a8 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/EhCacheQueryCache.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/EhCacheQueryCache.java
@@ -172,6 +172,10 @@ public class EhCacheQueryCache implements QueryCache {
         }
     }
 
+    public void removeGroup(String groupKey, Class<?> keyType, Class<?> 
valueType) {
+        removeGroup(groupKey);
+    }
+
     public void clear() {
         cacheManager.removalAll();
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
index 3c60e1e..ea48311 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/cache/MapQueryCache.java
@@ -19,9 +19,9 @@
 package org.apache.cayenne.cache;
 
 import java.io.Serializable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.query.QueryMetadata;
@@ -35,32 +35,32 @@ import org.apache.commons.collections.map.LRUMap;
  */
 public class MapQueryCache implements QueryCache, Serializable {
 
-    public static final int DEFAULT_CACHE_SIZE = 2000;
+    public static final int DEFAULT_CACHE_SIZE = 1000;
 
-    protected Map<String, CacheEntry> map;
+    static final String DEFAULT_CACHE_NAME = "cayenne.default.cache";
+
+    protected final Map<String, Map<String, List<?>>> cacheGroups;
+
+    private int maxSize;
 
     public MapQueryCache() {
         this(DEFAULT_CACHE_SIZE);
     }
 
-    @SuppressWarnings("unchecked")
     public MapQueryCache(int maxSize) {
-        this.map = new LRUMap(maxSize);
+        this.cacheGroups = new ConcurrentHashMap<>();
+        this.maxSize = maxSize;
     }
 
-    @SuppressWarnings("rawtypes")
     public List get(QueryMetadata metadata) {
         String key = metadata.getCacheKey();
         if (key == null) {
             return null;
         }
-
-        CacheEntry entry;
-        synchronized (this) {
-            entry = map.get(key);
+        Map<String, List<?>> map = createIfAbsent(metadata);
+        synchronized (map) {
+            return map.get(key);
         }
-
-        return (entry != null) ? entry.list : null;
     }
 
     /**
@@ -85,24 +85,25 @@ public class MapQueryCache implements QueryCache, 
Serializable {
         return result;
     }
 
-    @SuppressWarnings("rawtypes")
     public void put(QueryMetadata metadata, List results) {
         String key = metadata.getCacheKey();
-        if (key != null) {
-
-            CacheEntry entry = new CacheEntry();
-            entry.list = results;
-            entry.cacheGroup = metadata.getCacheGroup();
+        if (key == null) {
+            return;
+        }
 
-            synchronized (this) {
-                map.put(key, entry);
-            }
+        Map<String, List<?>> map = createIfAbsent(metadata);
+        synchronized (map) {
+            map.put(key, results);
         }
     }
 
     public void remove(String key) {
-        if (key != null) {
-            synchronized (this) {
+        if (key == null) {
+            return;
+        }
+
+        for(Map<String, List<?>> map : cacheGroups.values()) {
+            synchronized (map) {
                 map.remove(key);
             }
         }
@@ -110,33 +111,64 @@ public class MapQueryCache implements QueryCache, 
Serializable {
 
     public void removeGroup(String groupKey) {
         if (groupKey != null) {
-            synchronized (this) {
-                Iterator<CacheEntry> it = map.values().iterator();
-                while (it.hasNext()) {
-                    CacheEntry entry = it.next();
-                    if (entry.cacheGroup != null) {
-                        if (groupKey.equals(entry.cacheGroup)) {
-                            it.remove();
-                            break;
-                        }
-                    }
-                }
-            }
+            cacheGroups.remove(groupKey);
         }
     }
 
+    public void removeGroup(String groupKey, Class<?> keyType, Class<?> 
valueType) {
+        removeGroup(groupKey);
+    }
+
     public void clear() {
-        synchronized (this) {
-            map.clear();
-        }
+        cacheGroups.clear();
     }
 
     public int size() {
-        return map.size();
+        int size = 0;
+        for(Map<String, List<?>> map : cacheGroups.values()) {
+            synchronized (map) {
+                size += map.size();
+            }
+        }
+        return size;
     }
 
-    final static class CacheEntry implements Serializable {
-        List<?> list;
-        String cacheGroup;
+    protected Map<String, List<?>> createIfAbsent(QueryMetadata metadata) {
+        return createIfAbsent(cacheName(metadata));
+    }
+
+    protected Map<String, List<?>> createIfAbsent(String cacheName) {
+        Map<String, List<?>> cache = getCache(cacheName);
+        if (cache == null) {
+            cache = createCache(cacheName);
+        }
+
+        return cache;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected synchronized Map<String, List<?>> createCache(String cacheName) {
+        Map<String, List<?>> map = getCache(cacheName);
+        if(map != null) {
+            return map;
+        }
+        map = new LRUMap(maxSize);
+        cacheGroups.put(cacheName, map);
+        return map;
+    }
+
+    protected Map<String, List<?>> getCache(String name) {
+        return cacheGroups.get(name);
+    }
+
+    protected String cacheName(QueryMetadata metadata) {
+
+        String cacheGroup = metadata.getCacheGroup();
+        if (cacheGroup != null) {
+            return cacheGroup;
+        }
+
+        // no explicit cache group
+        return DEFAULT_CACHE_NAME;
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-server/src/main/java/org/apache/cayenne/cache/NestedQueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/NestedQueryCache.java 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/NestedQueryCache.java
index 2a465eb..8b96057 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/NestedQueryCache.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/NestedQueryCache.java
@@ -109,6 +109,11 @@ public class NestedQueryCache implements QueryCache {
         delegate.removeGroup(groupKey);
     }
 
+    @Override
+    public void removeGroup(String groupKey, Class<?> keyType, Class<?> 
valueType) {
+        delegate.removeGroup(groupKey, keyType, valueType);
+    }
+
     /**
      * Returns a shared cache size.
      * @see QueryCache#size()

http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-server/src/main/java/org/apache/cayenne/cache/OSQueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/OSQueryCache.java 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/OSQueryCache.java
index 67777f3..70e1bb0 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/cache/OSQueryCache.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/cache/OSQueryCache.java
@@ -337,6 +337,10 @@ public class OSQueryCache implements QueryCache {
         }
     }
 
+    public void removeGroup(String groupKey, Class<?> keyType, Class<?> 
valueType) {
+        removeGroup(groupKey);
+    }
+
     public void clear() {
         osCache.flushAll();
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-server/src/main/java/org/apache/cayenne/cache/QueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/cache/QueryCache.java 
b/cayenne-server/src/main/java/org/apache/cayenne/cache/QueryCache.java
index b615b77..fb21b83 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/cache/QueryCache.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/cache/QueryCache.java
@@ -67,6 +67,15 @@ public interface QueryCache {
     void removeGroup(String groupKey);
 
     /**
+     * Removes a group of entries identified by group key.
+     * Can be used if cache provider supports strictly typed caches.
+     * @see QueryCache#removeGroup(String)
+     *
+     * @since 4.0
+     */
+    void removeGroup(String groupKey, Class<?> keyType, Class<?> valueType);
+
+    /**
      * Clears all cache entries.
      *
      * @deprecated since 4.0. Please use implementation specific methods to 
perform cache management tasks.

http://git-wip-us.apache.org/repos/asf/cayenne/blob/67225b38/cayenne-server/src/test/java/org/apache/cayenne/cache/MockQueryCache.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/cache/MockQueryCache.java 
b/cayenne-server/src/test/java/org/apache/cayenne/cache/MockQueryCache.java
index b0b0a55..0705a60 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/cache/MockQueryCache.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/cache/MockQueryCache.java
@@ -44,6 +44,10 @@ public class MockQueryCache implements QueryCache {
     public void removeGroup(String groupKey) {
     }
 
+    public void removeGroup(String groupKey, Class<?> keyType, Class<?> 
valueType) {
+        removeGroup(groupKey);
+    }
+
     public int size() {
         return 0;
     }

Reply via email to