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));
+ }
+
+}