You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2014/01/18 18:25:43 UTC

git commit: ISIS-654: take-on of QueryResultsCache

Updated Branches:
  refs/heads/master 04baa307b -> b6a1bea37


ISIS-654: take-on of QueryResultsCache


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

Branch: refs/heads/master
Commit: b6a1bea37a7b38bb8cd1e135c6539a742a7337a0
Parents: 04baa30
Author: Dan Haywood <da...@apache.org>
Authored: Sat Jan 18 17:15:47 2014 +0000
Committer: Dan Haywood <da...@apache.org>
Committed: Sat Jan 18 17:15:47 2014 +0000

----------------------------------------------------------------------
 .../queryresultscache/QueryResultsCache.java    | 105 +++++++++++++++++++
 .../QueryResultsCacheTest.java                  |  69 ++++++++++++
 2 files changed, 174 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/b6a1bea3/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java b/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java
new file mode 100644
index 0000000..80954c7
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCache.java
@@ -0,0 +1,105 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.queryresultscache;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import javax.enterprise.context.RequestScoped;
+
+import com.google.common.collect.Maps;
+
+import org.apache.isis.applib.services.queryresultscache.QueryResultsCache.CacheKey;
+import org.apache.isis.applib.services.queryresultscache.QueryResultsCache.CacheValue;
+
+@RequestScoped
+public class QueryResultsCache {
+
+    static class CacheKey {
+        private final Class<?> callingClass;
+        private final String methodName;
+        private final Object[] keys;
+        
+        public CacheKey(Class<?> callingClass, String methodName, Object... keys) {
+            this.callingClass = callingClass;
+            this.methodName = methodName;
+            this.keys = keys;
+        }
+        
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            CacheKey other = (CacheKey) obj;
+            if (callingClass == null) {
+                if (other.callingClass != null)
+                    return false;
+            } else if (!callingClass.equals(other.callingClass))
+                return false;
+            if (!Arrays.equals(keys, other.keys))
+                return false;
+            if (methodName == null) {
+                if (other.methodName != null)
+                    return false;
+            } else if (!methodName.equals(other.methodName))
+                return false;
+            return true;
+        }
+        
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((callingClass == null) ? 0 : callingClass.hashCode());
+            result = prime * result + Arrays.hashCode(keys);
+            result = prime * result + ((methodName == null) ? 0 : methodName.hashCode());
+            return result;
+        }
+    }
+    
+    public static class CacheValue {
+        public CacheValue(Object object) {
+            this.object = object;
+        }
+        Object object;
+    }
+    
+    private final Map<CacheKey, CacheValue> cache = Maps.newHashMap();
+
+    @SuppressWarnings("unchecked")
+    public <T> T execute(Callable<T> callable, Class<?> callingClass, String methodName, Object... keys) {
+        try {
+            final CacheKey ck = new CacheKey(callingClass, methodName, keys);
+            final CacheValue cv = cache.get(ck);
+            if(cv != null) { 
+                return (T) cv.object;
+            }
+            // cache miss, so get the result, and cache
+            T result = callable.call();
+            cache.put(ck, new CacheValue(result));
+            return result;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/b6a1bea3/core/applib/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheTest.java
----------------------------------------------------------------------
diff --git a/core/applib/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheTest.java b/core/applib/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheTest.java
new file mode 100644
index 0000000..db2dbfd
--- /dev/null
+++ b/core/applib/src/test/java/org/apache/isis/applib/services/queryresultscache/QueryResultsCacheTest.java
@@ -0,0 +1,69 @@
+package org.apache.isis.applib.services.queryresultscache;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import java.util.concurrent.Callable;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class QueryResultsCacheTest {
+
+    private QueryResultsCache queryResultsCache;
+
+    @Before
+    public void setUp() throws Exception {
+        queryResultsCache = new QueryResultsCache();
+    }
+    @Test
+    public void execute() {
+        
+        String value = queryResultsCache.execute(new Callable<String>(){
+
+            @Override
+            public String call() throws Exception {
+                return "foo";
+            }
+            
+        }, QueryResultsCacheTest.class, "execute");
+        
+        assertThat(value, is("foo"));
+    }
+
+    @Test
+    public void caching() {
+        
+        final int[] i = new int[]{0};
+        
+        Callable<String> callable = new Callable<String>(){
+            
+            @Override
+            public String call() throws Exception {
+                i[0]++;
+                return "foo";
+            }
+            
+        };
+        assertThat(i[0], is(0));
+        assertThat(queryResultsCache.execute(callable, QueryResultsCacheTest.class, "caching", "a","b",1,2), is("foo"));
+        assertThat(i[0], is(1));
+        
+        // should be a cache hit
+        assertThat(queryResultsCache.execute(callable, QueryResultsCacheTest.class, "caching", "a","b",1,2), is("foo"));
+        assertThat(i[0], is(1));
+        
+        // changing any of the keys results in a cache miss
+        assertThat(queryResultsCache.execute(callable, QueryResultsCacheTest.class, "XXXcaching", "a","b",1,2), is("foo"));
+        assertThat(i[0], is(2));
+        assertThat(queryResultsCache.execute(callable, QueryResultsCache.class, "caching", "a","b",1,2), is("foo"));
+        assertThat(i[0], is(3));
+        assertThat(queryResultsCache.execute(callable, QueryResultsCacheTest.class, "caching", "XXX","b",1,2), is("foo"));
+        assertThat(i[0], is(4));
+        assertThat(queryResultsCache.execute(callable, QueryResultsCacheTest.class, "caching", "a","b",1,2, "x"), is("foo"));
+        assertThat(i[0], is(5));
+    }
+    
+}