From 2ae0ff78502343802f68569c6e5bb702a55d5533 Mon Sep 17 00:00:00 2001 From: ajs6f Date: Mon, 11 May 2015 09:35:02 -0400 Subject: [PATCH] Remove caching gear from jena-core and use instead that in jena-base --- .../jena/atlas/lib/cache/CacheSimpleTest.java | 43 ----- .../org/apache/jena/enhanced/EnhGraph.java | 22 +-- .../org/apache/jena/util/cache/Cache.java | 49 ------ .../apache/jena/util/cache/CacheControl.java | 70 -------- .../apache/jena/util/cache/CacheManager.java | 53 ------ .../jena/util/cache/EnhancedNodeCache.java | 120 ------------- .../org/apache/jena/util/cache/RandCache.java | 162 ------------------ .../jena/enhanced/test/TestPackage.java | 33 +--- .../java/org/apache/jena/util/TestCache.java | 125 -------------- .../org/apache/jena/util/TestPackage.java | 1 - 10 files changed, 10 insertions(+), 668 deletions(-) delete mode 100644 jena-base/src/test/java/org/apache/jena/atlas/lib/cache/CacheSimpleTest.java delete mode 100644 jena-core/src/main/java/org/apache/jena/util/cache/Cache.java delete mode 100644 jena-core/src/main/java/org/apache/jena/util/cache/CacheControl.java delete mode 100644 jena-core/src/main/java/org/apache/jena/util/cache/CacheManager.java delete mode 100644 jena-core/src/main/java/org/apache/jena/util/cache/EnhancedNodeCache.java delete mode 100644 jena-core/src/main/java/org/apache/jena/util/cache/RandCache.java delete mode 100644 jena-core/src/test/java/org/apache/jena/util/TestCache.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 deleted file mode 100644 index 41f8dd5bbf3..00000000000 --- a/jena-base/src/test/java/org/apache/jena/atlas/lib/cache/CacheSimpleTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 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()); - } -} diff --git a/jena-core/src/main/java/org/apache/jena/enhanced/EnhGraph.java b/jena-core/src/main/java/org/apache/jena/enhanced/EnhGraph.java index 1254675417f..efecff7053f 100644 --- a/jena-core/src/main/java/org/apache/jena/enhanced/EnhGraph.java +++ b/jena-core/src/main/java/org/apache/jena/enhanced/EnhGraph.java @@ -18,9 +18,10 @@ package org.apache.jena.enhanced; +import org.apache.jena.atlas.lib.Cache; +import org.apache.jena.atlas.lib.CacheFactory; import org.apache.jena.graph.* ; import org.apache.jena.rdf.model.RDFNode ; -import org.apache.jena.util.cache.* ; /** TODO: remove the polymorphic aspect of EnhGraphs. @@ -41,11 +42,10 @@ public class EnhGraph /** The graph that this enhanced graph is wrapping */ protected Graph graph; - /** Counter that helps to ensure that caches are kept distinct */ - static private int cnt = 0; - /** Cache of enhanced nodes that have been created */ - protected Cache enhNodes = CacheManager.createCache( CacheManager.ENHNODECACHE, "EnhGraph-" + cnt++, 1000 ); + // TODO The cache size of 1000 seems to be a "magic number". Perhaps this could be explained + // or parameterized? + protected Cache enhNodes = CacheFactory.createCache(1000); /** The unique personality that is bound to this polymorphic instace */ private Personality personality; @@ -130,7 +130,7 @@ final public boolean isIsomorphicWith(EnhGraph eg){ public X getNodeAs( Node n, Class interf ) { // We use a cache to avoid reconstructing the same Node too many times. - EnhNode eh = (EnhNode) enhNodes.get( n ); + EnhNode eh = (EnhNode) enhNodes.getIfPresent( n ); if (eh == null) { // not in the cache, so build a new one @@ -142,19 +142,11 @@ public X getNodeAs( Node n, Class interf ) return eh.viewAs( interf ); } - /** - * Answer the cache controlle for this graph - * @return A cache controller object - */ - public CacheControl getNodeCacheControl() { - return enhNodes; - } - /** * Set the cache controller object for this graph * @param cc The cache controller */ - public void setNodeCache(Cache cc) { + public void setNodeCache(Cache cc) { enhNodes = cc; } diff --git a/jena-core/src/main/java/org/apache/jena/util/cache/Cache.java b/jena-core/src/main/java/org/apache/jena/util/cache/Cache.java deleted file mode 100644 index 66c498997d5..00000000000 --- a/jena-core/src/main/java/org/apache/jena/util/cache/Cache.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.util.cache; - -/** A caching store for objects. - * - *

A caching store will hold on to some objects for some - * time, but may fail to store them. It is used as an - * optimization, so that objects that have already been - * constructed, need not be made again. The null object - * should not be stored under a key as there is no way - * to distingish this from a missing object.

- * - *

Cache objects are usually created using the {@link CacheManager }.

- * - *

An object is associated with a key which is used to - * identify the object on retrieval. Only one object may be - * associated with a key.

- */ -public interface Cache extends CacheControl { - /** Get and object from the cache, if it is there. - * @param key the key for the object sought - * @return the object associated with the key, or null if - * the key is not found in the cache - */ - public Object get(Object key); - /** Store an object in the cache - * @param key the key for the object being stored - * @param value the object stored under the key - * - */ - public void put(Object key, Object value); -} diff --git a/jena-core/src/main/java/org/apache/jena/util/cache/CacheControl.java b/jena-core/src/main/java/org/apache/jena/util/cache/CacheControl.java deleted file mode 100644 index 4614936fe23..00000000000 --- a/jena-core/src/main/java/org/apache/jena/util/cache/CacheControl.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.util.cache; - -/** An interface for controlling the behaviour of a cache. - * - *

This is separated from the main {@link Cache } interface - * so that methods return an object that can set control - * parameters on a cache, without granting read/write access - * to the cache itself.

- * - *

Cache's may be enabled or disabled. A disabled cache - * is a silent cache; it will silently not return objects - * from its store and not update its store. It will operate - * as if the cache always missed.

- * - *

Cache's keep statistics on their accesses. On a long - * running cache the numbers may exceeed the size of the - * variables counting the statistics, in which case, the - * fields counting gets hits and puts are reduced - * proportionately.

- */ -public interface CacheControl { - - /** Get the enabled state of the cache - * @return The enabled state of the cache - */ - public boolean getEnabled(); - - /** Set the enabled state of a cache - * @param enabled the new enabled state of the cache - * @return the previous enabled state of the cache - */ - public boolean setEnabled(boolean enabled); - - /** Clear the cache's store - */ - public void clear(); - - /** Return number of gets on this cache. - * - * - * @return The number of gets on this cache. - */ - public long getGets(); - /** Get the number of puts on this cache - * @return the number of puts - */ - public long getPuts(); - /** Get the number of hits on this cache - * @return the number of hits - */ - public long getHits(); -} diff --git a/jena-core/src/main/java/org/apache/jena/util/cache/CacheManager.java b/jena-core/src/main/java/org/apache/jena/util/cache/CacheManager.java deleted file mode 100644 index c63431b03f7..00000000000 --- a/jena-core/src/main/java/org/apache/jena/util/cache/CacheManager.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.util.cache; - -/** A factory for creating cache objects - */ - -public class CacheManager { - - public static final String RAND = "RAND"; - - public static final String ENHNODECACHE = "ENHNODECACHE"; - - /** Creates new Manager */ - private CacheManager() { - } - - /** Create a new cache - * @param type The type of cache to create. This should be one - * of the standard cache types defined in this class. - * @param name A name for the cache. This should be unique and - * may be used to identify the cache in logging and - * other operations. To ensure uniqueness it is - * suggested that cache's be given names similar to - * full java names such as org.apache.jena.graph.Node.NodeCache. - * @param size The size of the cache in terms of the number of - * objects it can store. - * @return a newly created cache object - * - */ - public static Cache createCache(String type, String name, int size) { - // for now we just have one type - if (type.equals(RAND)) return new RandCache( name, size ); - if (type.equals(ENHNODECACHE)) return new EnhancedNodeCache( name, size ); - throw new Error( "Bad cache type: " + type ); - } -} diff --git a/jena-core/src/main/java/org/apache/jena/util/cache/EnhancedNodeCache.java b/jena-core/src/main/java/org/apache/jena/util/cache/EnhancedNodeCache.java deleted file mode 100644 index 115e1179e97..00000000000 --- a/jena-core/src/main/java/org/apache/jena/util/cache/EnhancedNodeCache.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.util.cache; - -import org.apache.jena.enhanced.EnhNode ; -import org.apache.jena.graph.Node ; - -/** - EnhancedNodeCache - the cache to use for enhanced nodes (mapping a Node - to one of the enhanced nodes it can represent). - -

The cache methods do not need to be synchronised. Java guarantees that - access/update of reference values is atomic. The get method - does a single read operation of the cache, and then checks that the - returned element matches the key, only returning legal objects; changes - to the cache subsequently don't affect the correctness of the result. - -

The put method updates the appropriate cache entry as - a one-shot deal. gets on different slots don't matter. Gets on the same - slot have either completed (and thus don't care about the change) or - are about to happen (and will be equally happy with the old or new - value). - -

Synchronisation *is* required when updating the EnhNode sibling ring, - but that doesn't happen here. -*/ -public class EnhancedNodeCache implements Cache - { - protected String name; - - protected EnhNode [] elements; - - protected boolean enabled = true; - - protected long gets, puts, hits; - - public EnhancedNodeCache( String name, int size ) - { this.name = name; - this.elements = new EnhNode[size]; } - - @Override - public Object get( Object key ) - { - if (enabled) - { - gets += 1; - Node n = (Node) key; - int i = hashNode( n ); - EnhNode result = elements[i]; - if (result != null && result.asNode().equals( key )) - { - hits += 1; - return result; - } - } - return null; - } - - @Override - public void put( Object key, Object value ) - { - if (enabled) - { - puts += 1; - Node n = (Node) key; - int i = hashNode( n ) ; - elements[i] = (EnhNode) value; - } - } - - /** - * @param n - * @return - */ - protected int hashNode( Node n ) - { return (n.hashCode() & 0x7fffffff) % elements.length; } - - @Override - public boolean getEnabled() - { return enabled; } - - @Override - public boolean setEnabled( boolean enabled ) - { boolean result = this.enabled; - this.enabled = enabled; - return result; } - - @Override - public void clear() - { for (int i = 0; i < elements.length; i += 1) elements[i] = null; } - - @Override - public long getGets() - { return gets; } - - @Override - public long getPuts() - { return puts; } - - @Override - public long getHits() - { return hits; } - - } diff --git a/jena-core/src/main/java/org/apache/jena/util/cache/RandCache.java b/jena-core/src/main/java/org/apache/jena/util/cache/RandCache.java deleted file mode 100644 index 4b6c500e80c..00000000000 --- a/jena-core/src/main/java/org/apache/jena/util/cache/RandCache.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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.util.cache; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class RandCache implements Cache, CacheControl { - int size; - int threshhold; - boolean enabled = true; - // so we can identify caches - String name; // e.g. when logging - - HashMap map; - Collection collection; - - protected static Logger logger = LoggerFactory.getLogger(RandCache.class); - - long gets = 0; - long puts = 0; - long hits = 0; - - /** Creates new RandCache */ - RandCache(String name, int size) { - this.size = size; - try { - map = new HashMap<>(size * 100 / 75); // based on .75 loadfactor - } catch (IllegalArgumentException e) { - if ("Illegal load factor: NaN".equals(e.getMessage())) { - // This strange construction needs explanation. - // When we implemented XSDbase64Binary/XSDhexBinary support involving use - // of byte[] we started seeing this error here. Since the default loadfactor - // is a static final constant in HashMap this should never be possible. - // It only happens under JDK 1.4.1 not under 1.3.1 nor 1.4.2. - // The retry, however does seem to work and hence gives us a work around - // which is completely mysterious but at least enables the unit tests to pass. - // - der 4/5/04 - logger.warn("Detected a NaN anomaly believed to be due to use of JDK 1.4.1"); - map = new HashMap<>(size*100/75, 0.75f); - } else { - throw e; - } - } - threshhold = size; - if (threshhold < 2) { - throw new Error("Cache size too small: " + size); - } - collection = map.values(); - } - - @Override - public synchronized Object get(Object key) { - if (enabled) { - if (gets == Long.MAX_VALUE) { - forgetStats(); - } - gets++; - Object result = map.get(key); - if (result != null) { - hits++; - } - return result; - } else { - return null; - } - } - - @Override - public synchronized void put(Object key, Object value) { - - // don't allow null values - if (value == null) { - throw new NullPointerException(); - } - - if (enabled) { - if (puts == Long.MAX_VALUE) { - forgetStats(); - } - puts++; - if (map.size() >= threshhold) { - makeSpace(); - } - map.put(key, value); - } - } - - protected void makeSpace() { - Iterator iter = collection.iterator(); - - // we are going to remove every 3rd member of the cache - int size = map.size(); - int i = 3; - while (i < size ) { - iter.next(); - iter.remove(); - iter.next(); - iter.next(); - i = i + 3; - } - } - - @Override - public synchronized boolean getEnabled() { - return enabled; - } - - @Override - public synchronized boolean setEnabled(boolean enabled) { - boolean result = enabled; - this.enabled = enabled; - return result; - } - - @Override - public synchronized void clear() { - map.clear(); - } - - @Override - public synchronized long getHits() { - return hits; - } - - @Override - public synchronized long getGets() { - return gets; - } - - @Override - public synchronized long getPuts() { - return puts; - } - - protected void forgetStats() { - gets = gets/2; - puts = puts/2; - hits = hits/2; - } - -} diff --git a/jena-core/src/test/java/org/apache/jena/enhanced/test/TestPackage.java b/jena-core/src/test/java/org/apache/jena/enhanced/test/TestPackage.java index cd6ba8411f7..f8955602e9a 100644 --- a/jena-core/src/test/java/org/apache/jena/enhanced/test/TestPackage.java +++ b/jena-core/src/test/java/org/apache/jena/enhanced/test/TestPackage.java @@ -290,23 +290,7 @@ private void follow(String title, Personality p) { }); assertTrue("Model cache test",nodes[0].asProperty().anObject()==nodes[2]); } - private void cache(String title, Personality p) { - Graph g = Factory.createGraphMem(); - TestModel model = new TestModelImpl(g,p); - // create some data - graphAdd( g, "a b a;" ); - - // get the same node in two different ways. - assertTrue("Caching is on",model.aSubject().asObject()==model.anObject()); - - ((TestModelImpl)model).getNodeCacheControl().setEnabled(false); - - - // get the same node in two different ways; if there isn't any caching - // then we reconstruct the node. - assertFalse("Caching is off",model.aSubject()==model.anObject()); - - } + public static void testSplitBasic() { basic("Split: ",split); } @@ -319,25 +303,14 @@ public void testSplitFollow() { public void testComboFollow() { follow("Combo: ",combo); } - - public void testSplitCache() { - cache("Split: ",split); - } - public void testComboCache() { - cache("Combo: ",combo); - } - + public static void testBitOfBothBasic() { basic("bob: ",bitOfBoth); } public void testBitOfBothFollow() { follow("bob: ",bitOfBoth); } - - public void testBitOfBothCache() { - cache("bob: ",bitOfBoth); - } - + public static void testBitOfBothSurprise() { // bitOfBoth is a surprising personality ... // we can have two different java objects implementing the same interface. diff --git a/jena-core/src/test/java/org/apache/jena/util/TestCache.java b/jena-core/src/test/java/org/apache/jena/util/TestCache.java deleted file mode 100644 index 9547c9de030..00000000000 --- a/jena-core/src/test/java/org/apache/jena/util/TestCache.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.util; - -import junit.framework.*; -import org.apache.jena.util.cache.* ; - - -public class TestCache extends TestCase - { - - public TestCache(String name) - { super( name ); } - - public static TestSuite suite() { - TestSuite suite = new TestSuite("Cache"); - suite.addTest( new CacheTestCase(CacheManager.RAND)); - // suite.addTest( new CacheTestCase(CacheManager.ENHNODECACHE)); - return suite; - } - - static class CacheTestCase extends TestCase { - String cacheType; - - CacheTestCase(String cacheType) { - super( cacheType ); - this.cacheType = cacheType; - } - - @Override - protected void runTest() { - testCache(); - } - - public void testCache() { - testCacheCreation(cacheType); - testCacheSimpleReturn(cacheType); - testFillTheCache(cacheType); - } - - public void testCacheCreation(String type) { - Cache c1 = CacheManager.createCache(type, "c1", 100); - try { - Cache c2 = CacheManager.createCache(type, "c2", 1); - assertTrue("Missing error on bad cache size: " + type, false); - } catch (Error e) {} - } - - public void testCacheSimpleReturn(String type) { - - int size = 100; - // this test does not fill the cache - Cache c1 = CacheManager.createCache(type, "c1", size); - - String k1 = "one"; - String k2 = k1; - String k3 = k2; - Integer v1 = -1; - Integer v2 = v1; - Integer v3 = v2; - c1.put(k1, v1); - - for (int i=0; i