Clean caching code. This closes #57
Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f3a8969f Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f3a8969f Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f3a8969f Branch: refs/heads/add-contract-tests Commit: f3a8969f1b60df2706d4cc9dc7966816500af4b8 Parents: 36b9b12 Author: Andy Seaborne <[email protected]> Authored: Mon May 11 19:11:00 2015 +0100 Committer: Andy Seaborne <[email protected]> Committed: Mon May 11 19:11:00 2015 +0100 ---------------------------------------------------------------------- .../apache/jena/atlas/lib/cache/CacheGuava.java | 14 ++--- .../jena/atlas/lib/cache/CacheSetImpl.java | 1 - .../jena/atlas/lib/cache/CacheSimple.java | 24 ++++----- .../java/org/apache/jena/atlas/lib/TS_Lib.java | 2 + .../org/apache/jena/atlas/lib/TestCache2.java | 13 ++--- .../jena/atlas/lib/cache/CacheSimpleTest.java | 43 +++++++++++++++ .../jena/atlas/lib/cache/TestCacheSimple.java | 57 ++++++++++++++++++++ 7 files changed, 124 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java index 9beffaf..8dd77e6 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheGuava.java @@ -29,10 +29,11 @@ import org.apache.jena.ext.com.google.common.cache.CacheBuilder ; import org.apache.jena.ext.com.google.common.cache.RemovalListener ; /** Wrapper around a shaded com.google.common.cache */ -final -public class CacheGuava<K,V> implements Cache<K, V> +final public class CacheGuava<K,V> implements Cache<K, V> + { private BiConsumer<K, V> dropHandler = null ; + private org.apache.jena.ext.com.google.common.cache.Cache<K,V> cache ; public CacheGuava(int size) @@ -69,11 +70,10 @@ public class CacheGuava<K,V> implements Cache<K, V> @Override public void put(K key, V thing) { - if ( thing == null ) { - cache.invalidate(key); - return ; - } - cache.put(key, thing) ; + if (thing == null) + cache.invalidate(key); + else + cache.put(key, thing); } @Override http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java index 8a24d26..d718119 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSetImpl.java @@ -27,7 +27,6 @@ import org.apache.jena.atlas.lib.CacheSet ; /** Cache set */ public class CacheSetImpl<T> implements CacheSet<T> { - // LinkHashSet does not have LRU support. static Object theOnlyValue = new Object() ; Cache<T, Object> cacheMap = null ; http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java index ddd81f6..9e09d23 100644 --- a/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java +++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/cache/CacheSimple.java @@ -72,11 +72,11 @@ public class CacheSimple<K,V> implements Cache<K,V> return getIfPresent(key) != null ; } - // Return key index : -(index+1) if the key does not match + // Return key index : -(index+1) if the key slot is empty. private final int index(K key) { int x = (key.hashCode()&0x7fffffff) % size ; - if ( keys[x] != null && keys[x].equals(key) ) + if ( keys[x] != null ) return x ; return -x-1 ; } @@ -104,19 +104,17 @@ public class CacheSimple<K,V> implements Cache<K,V> @Override public void put(K key, V thing) { - int x = index(key) ; - V old = null ; - if ( x < 0 ) - // New. - x = decode(x) ; - else - { - // Drop the old K->V - old = values[x] ; + int x = index(key) ; + x = decode(x) ; + V old = values[x] ; + // Drop the old K->V + if ( old != null ) { + if ( old.equals(thing) ) + // Replace like-with-like. + return ; if ( dropHandler != null ) dropHandler.accept(keys[x], old) ; - if ( old != null ) - currentSize-- ; + currentSize-- ; } // Already decremented if we are overwriting a full slot. http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java index ac543c0..a67532b 100644 --- a/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TS_Lib.java @@ -19,6 +19,7 @@ package org.apache.jena.atlas.lib; +import org.apache.jena.atlas.lib.cache.TestCacheSimple; import org.junit.runner.RunWith ; import org.junit.runners.Suite ; @@ -48,6 +49,7 @@ import org.junit.runners.Suite ; , TestFilenameProcessing.class , TestNumberUtils.class , TestDateTimeUtils.class + , TestCacheSimple.class } ) public class TS_Lib http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java index 2e640f3..d1af0db 100644 --- a/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/TestCache2.java @@ -23,7 +23,6 @@ import java.util.concurrent.Callable ; import org.apache.jena.atlas.junit.BaseTest ; import org.apache.jena.atlas.lib.Cache ; import org.apache.jena.atlas.lib.CacheFactory ; -import org.apache.jena.atlas.lib.cache.Cache1 ; import org.junit.Test ; // Non-parameterized tests @@ -32,7 +31,7 @@ public class TestCache2 extends BaseTest // Cache1 @Test public void cache_10() { - Cache<Integer, String> cache = new Cache1<>() ; + Cache<Integer, String> cache = CacheFactory.createOneSlotCache() ; String str = cache.getIfPresent(1) ; assertNull(str) ; @@ -53,13 +52,9 @@ public class TestCache2 extends BaseTest - static Callable<String> getter(final Integer key) { - return new Callable<String>() { - @Override - public String call() { - return key.toString() ; } - } ; - } + static Callable<String> getter(final Integer key) { + return () -> key.toString(); + } // Cache + getters @Test public void cacheGetter_1() http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/CacheSimpleTest.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/CacheSimpleTest.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/CacheSimpleTest.java new file mode 100644 index 0000000..41f8dd5 --- /dev/null +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/CacheSimpleTest.java @@ -0,0 +1,43 @@ +/* + * 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.jena.atlas.lib.cache; + +import static java.util.stream.Collectors.toMap; +import static java.util.stream.IntStream.rangeClosed; +import static org.junit.Assert.assertEquals; + +import org.apache.jena.atlas.lib.Cache; +import org.junit.Test; + +/** + * Simple test to ensure that {@link CacheSimple} evidences the fixed-size + * behavior we desire. + */ +public class CacheSimpleTest { + + @Test + public void testFixedSize() { + final int maxSize = 5; + final int submittedEntries = 10; + final Cache<Integer, Object> testCache = new CacheSimple<>(maxSize); + rangeClosed(1, submittedEntries).boxed().collect(toMap(k -> k, v -> 1)) + .forEach(testCache::put); + assertEquals("Test cache failed to maintain fixed size!", maxSize, testCache.size()); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/f3a8969f/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/TestCacheSimple.java ---------------------------------------------------------------------- diff --git a/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/TestCacheSimple.java b/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/TestCacheSimple.java new file mode 100644 index 0000000..602be6c --- /dev/null +++ b/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/TestCacheSimple.java @@ -0,0 +1,57 @@ +/* + * 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.jena.atlas.lib.cache; + +import static java.util.stream.Collectors.toMap; +import static java.util.stream.IntStream.rangeClosed; + +import org.apache.jena.atlas.junit.BaseTest; +import org.apache.jena.atlas.lib.Cache; +import org.junit.Test; + +/** + * Simple test to ensure that {@link CacheSimple} evidences the fixed-size + * behavior we desire. + */ +public class TestCacheSimple extends BaseTest { + + @Test + public void testFixedSize() { + final int maxSize = 5; + final int submittedEntries = 10; + final Cache<Integer, Object> testCache = new CacheSimple<>(maxSize); + rangeClosed(1, submittedEntries).boxed().collect(toMap(k -> k, v -> 1)) + .forEach(testCache::put); + assertEquals("Test cache failed to maintain fixed size!", maxSize, testCache.size()); + } + + @Test + public void testReplace() { + final Integer key = 1 ; + final String value1 = "A" ; + final String value2 = "B" ; + + final Cache<Integer, Object> testCache = new CacheSimple<>(5); + testCache.put(1, value1); + testCache.put(1, value2); + assertEquals("Wrong size", 1, testCache.size()) ; + assertEquals("Wrong slot contents", value2, testCache.getIfPresent(1)) ; + } + +}
