Repository: groovy Updated Branches: refs/heads/GROOVY_2_5_X 9d1df4570 -> 5f956a633
Rename SimpleCache to CommonCache (cherry picked from commit a6bbf7e) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/485eacca Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/485eacca Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/485eacca Branch: refs/heads/GROOVY_2_5_X Commit: 485eacca146cdcb6c9ddb08c4cd5e3b555aa862a Parents: 9d1df45 Author: sunlan <[email protected]> Authored: Sun Dec 10 01:57:33 2017 +0800 Committer: sunlan <[email protected]> Committed: Sun Dec 10 02:13:35 2017 +0800 ---------------------------------------------------------------------- src/main/groovy/lang/GroovyClassLoader.java | 6 +- .../groovy/runtime/memoize/CommonCache.java | 192 +++++++++++++++++++ .../groovy/runtime/memoize/SimpleCache.java | 192 ------------------- .../groovy/runtime/memoize/CommonCacheTest.java | 161 ++++++++++++++++ .../groovy/runtime/memoize/SimpleCacheTest.java | 161 ---------------- 5 files changed, 356 insertions(+), 356 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/485eacca/src/main/groovy/lang/GroovyClassLoader.java ---------------------------------------------------------------------- diff --git a/src/main/groovy/lang/GroovyClassLoader.java b/src/main/groovy/lang/GroovyClassLoader.java index 134d887..47e5444 100644 --- a/src/main/groovy/lang/GroovyClassLoader.java +++ b/src/main/groovy/lang/GroovyClassLoader.java @@ -44,7 +44,7 @@ import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.runtime.IOGroovyMethods; import org.codehaus.groovy.runtime.InvokerHelper; import org.codehaus.groovy.runtime.memoize.EvictableCache; -import org.codehaus.groovy.runtime.memoize.SimpleCache; +import org.codehaus.groovy.runtime.memoize.CommonCache; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -95,13 +95,13 @@ public class GroovyClassLoader extends URLClassLoader { /** * this cache contains the loaded classes or PARSING, if the class is currently parsed */ - protected final SimpleCache<String, Class> classCache = new SimpleCache<String, Class>(); + protected final CommonCache<String, Class> classCache = new CommonCache<String, Class>(); /** * This cache contains mappings of file name to class. It is used * to bypass compilation. */ - protected final SimpleCache<String, Class> sourceCache = new SimpleCache<String, Class>(); + protected final CommonCache<String, Class> sourceCache = new CommonCache<String, Class>(); private final CompilerConfiguration config; private String sourceEncoding; http://git-wip-us.apache.org/repos/asf/groovy/blob/485eacca/src/main/org/codehaus/groovy/runtime/memoize/CommonCache.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/runtime/memoize/CommonCache.java b/src/main/org/codehaus/groovy/runtime/memoize/CommonCache.java new file mode 100644 index 0000000..ee6e0a9 --- /dev/null +++ b/src/main/org/codehaus/groovy/runtime/memoize/CommonCache.java @@ -0,0 +1,192 @@ +/* + * 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.codehaus.groovy.runtime.memoize; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * + * Represents a simple cache, which is thread safe and backed by a {@link java.util.Map} instance + * + * @param <K> type of the keys + * @param <V> type of the values + * + * @since 2.5.0 + */ +public class CommonCache<K, V> implements EvictableCache<K, V> { + private final Map<K, V> map; + private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private final ReentrantReadWriteLock.ReadLock readLock = rwl.readLock(); + private final ReentrantReadWriteLock.WriteLock writeLock = rwl.writeLock(); + + public CommonCache() { + this(new HashMap<K, V>()); + } + + public CommonCache(Map<K, V> map) { + this.map = map; + } + + @Override + public V get(K key) { + if (null == key) { + return null; + } + + readLock.lock(); + try { + return map.get(key); + } finally { + readLock.unlock(); + } + } + + @Override + public V put(K key, V value) { + writeLock.lock(); + try { + return map.put(key, value); + } finally { + writeLock.unlock(); + } + + } + + @Override + public V getAndPut(K key, ValueProvider<K, V> valueProvider) { + return getAndPut(key, valueProvider, true); + } + + public V getAndPut(K key, ValueProvider<K, V> valueProvider, boolean shouldCache) { + if (null == key) { + return null; + } + + V value; + + readLock.lock(); + try { + value = map.get(key); + if (null != value) { + return value; + } + } finally { + readLock.unlock(); + } + + writeLock.lock(); + try { + // try to find the cached value again + value = map.get(key); + if (null != value) { + return value; + } + + value = null == valueProvider ? null : valueProvider.provide(key); + if (shouldCache && null != value) { + map.put(key, value); + } + } finally { + writeLock.unlock(); + } + + return value; + } + + @Override + public Collection<V> values() { + readLock.lock(); + try { + return map.values(); + } finally { + readLock.unlock(); + } + } + + @Override + public Set<K> keys() { + readLock.lock(); + try { + return map.keySet(); + } finally { + readLock.unlock(); + } + } + + @Override + public int size() { + readLock.lock(); + try { + return map.size(); + } finally { + readLock.unlock(); + } + } + + @Override + public V remove(K key) { + writeLock.lock(); + try { + return map.remove(key); + } finally { + writeLock.unlock(); + } + } + + @Override + public Collection<V> clear() { + Collection<V> values; + + writeLock.lock(); + try { + values = map.values(); + map.clear(); + } finally { + writeLock.unlock(); + } + + return values; + } + + @Override + public void cleanUpNullReferences() { + writeLock.lock(); + try { + List<K> keys = new LinkedList<>(); + + for (Map.Entry<K, V> entry : map.entrySet()) { + if (null == entry.getValue()) { + keys.add(entry.getKey()); + } + } + + for (K key : keys) { + map.remove(key); + } + } finally { + writeLock.unlock(); + } + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/485eacca/src/main/org/codehaus/groovy/runtime/memoize/SimpleCache.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/runtime/memoize/SimpleCache.java b/src/main/org/codehaus/groovy/runtime/memoize/SimpleCache.java deleted file mode 100644 index 15c1a8e..0000000 --- a/src/main/org/codehaus/groovy/runtime/memoize/SimpleCache.java +++ /dev/null @@ -1,192 +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.codehaus.groovy.runtime.memoize; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * - * Represents a simple cache, which is thread safe and backed by a {@link java.util.Map} instance - * - * @param <K> type of the keys - * @param <V> type of the values - * - * @since 2.5.0 - */ -public class SimpleCache<K, V> implements EvictableCache<K, V> { - private final Map<K, V> map; - private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); - private final ReentrantReadWriteLock.ReadLock readLock = rwl.readLock(); - private final ReentrantReadWriteLock.WriteLock writeLock = rwl.writeLock(); - - public SimpleCache() { - this(new HashMap<K, V>()); - } - - public SimpleCache(Map<K, V> map) { - this.map = map; - } - - @Override - public V get(K key) { - if (null == key) { - return null; - } - - readLock.lock(); - try { - return map.get(key); - } finally { - readLock.unlock(); - } - } - - @Override - public V put(K key, V value) { - writeLock.lock(); - try { - return map.put(key, value); - } finally { - writeLock.unlock(); - } - - } - - @Override - public V getAndPut(K key, ValueProvider<K, V> valueProvider) { - return getAndPut(key, valueProvider, true); - } - - public V getAndPut(K key, ValueProvider<K, V> valueProvider, boolean shouldCache) { - if (null == key) { - return null; - } - - V value; - - readLock.lock(); - try { - value = map.get(key); - if (null != value) { - return value; - } - } finally { - readLock.unlock(); - } - - writeLock.lock(); - try { - // try to find the cached value again - value = map.get(key); - if (null != value) { - return value; - } - - value = null == valueProvider ? null : valueProvider.provide(key); - if (shouldCache && null != value) { - map.put(key, value); - } - } finally { - writeLock.unlock(); - } - - return value; - } - - @Override - public Collection<V> values() { - readLock.lock(); - try { - return map.values(); - } finally { - readLock.unlock(); - } - } - - @Override - public Set<K> keys() { - readLock.lock(); - try { - return map.keySet(); - } finally { - readLock.unlock(); - } - } - - @Override - public int size() { - readLock.lock(); - try { - return map.size(); - } finally { - readLock.unlock(); - } - } - - @Override - public V remove(K key) { - writeLock.lock(); - try { - return map.remove(key); - } finally { - writeLock.unlock(); - } - } - - @Override - public Collection<V> clear() { - Collection<V> values; - - writeLock.lock(); - try { - values = map.values(); - map.clear(); - } finally { - writeLock.unlock(); - } - - return values; - } - - @Override - public void cleanUpNullReferences() { - writeLock.lock(); - try { - List<K> keys = new LinkedList<>(); - - for (Map.Entry<K, V> entry : map.entrySet()) { - if (null == entry.getValue()) { - keys.add(entry.getKey()); - } - } - - for (K key : keys) { - map.remove(key); - } - } finally { - writeLock.unlock(); - } - } -} http://git-wip-us.apache.org/repos/asf/groovy/blob/485eacca/src/test/org/codehaus/groovy/runtime/memoize/CommonCacheTest.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/memoize/CommonCacheTest.java b/src/test/org/codehaus/groovy/runtime/memoize/CommonCacheTest.java new file mode 100644 index 0000000..9bbb08b --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/memoize/CommonCacheTest.java @@ -0,0 +1,161 @@ +/* + * 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.codehaus.groovy.runtime.memoize; + +import org.apache.groovy.util.Maps; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.LinkedHashMap; + +public class CommonCacheTest { + @Test + public void get() { + CommonCache<String, String> sc = + new CommonCache<>( + new LinkedHashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", "Shanghai") + ) + ); + + Assert.assertEquals("Daniel", sc.get("name")); + Assert.assertEquals("Male", sc.get("gender")); + Assert.assertEquals("Shanghai", sc.get("city")); + Assert.assertNull(sc.get("foo")); + } + + @Test + public void put() { + CommonCache<String, String> sc = new CommonCache<>(); + + Assert.assertNull(sc.put("name", "Daniel")); + Assert.assertEquals("Daniel", sc.get("name")); + + Assert.assertEquals("Daniel", sc.put("name", "sunlan")); + Assert.assertEquals("sunlan", sc.get("name")); + } + + @Test + public void getAndPut() { + CommonCache<String, String> sc = new CommonCache<>(); + + EvictableCache.ValueProvider vp = + new EvictableCache.ValueProvider<String, String>() { + @Override + public String provide(String key) { + return "Chinese"; + } + }; + + Assert.assertEquals("Chinese", sc.getAndPut("language", vp,false)); + Assert.assertNull(sc.get("language")); + + Assert.assertEquals("Chinese", sc.getAndPut("language", vp)); + Assert.assertEquals("Chinese", sc.get("language")); + } + + @Test + public void values() { + CommonCache<String, String> sc = + new CommonCache<>( + new LinkedHashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", "Shanghai") + ) + ); + + Assert.assertArrayEquals(new String[] {"Daniel", "Male", "Shanghai"}, sc.values().toArray(new String[0])); + } + + @Test + public void keys() { + CommonCache<String, String> sc = + new CommonCache<>( + new LinkedHashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", "Shanghai") + ) + ); + + Assert.assertArrayEquals(new String[] {"name", "gender", "city"}, sc.keys().toArray(new String[0])); + } + + @Test + public void size() { + CommonCache<String, String> sc = + new CommonCache<>( + new LinkedHashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", "Shanghai") + ) + ); + + Assert.assertEquals(3, sc.size()); + } + + @Test + public void remove() { + CommonCache<String, String> sc = + new CommonCache<>( + new HashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", "Shanghai") + ) + ); + + Assert.assertEquals("Shanghai", sc.remove("city")); + Assert.assertNull(sc.get("city")); + } + + @Test + public void clear() { + CommonCache<String, String> sc = + new CommonCache<>( + new LinkedHashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", "Shanghai") + ) + ); + + Assert.assertArrayEquals(new String[] {"Daniel", "Male", "Shanghai"}, sc.values().toArray(new String[0])); + } + + @Test + public void cleanUpNullReferences() { + CommonCache<String, String> sc = + new CommonCache<>( + new LinkedHashMap<>( + Maps.of("name", "Daniel", + "gender", "Male", + "city", null) + ) + ); + + sc.cleanUpNullReferences(); + Assert.assertArrayEquals(new String[] {"Daniel", "Male"}, sc.values().toArray(new String[0])); + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/485eacca/src/test/org/codehaus/groovy/runtime/memoize/SimpleCacheTest.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/memoize/SimpleCacheTest.java b/src/test/org/codehaus/groovy/runtime/memoize/SimpleCacheTest.java deleted file mode 100644 index 55ce393..0000000 --- a/src/test/org/codehaus/groovy/runtime/memoize/SimpleCacheTest.java +++ /dev/null @@ -1,161 +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.codehaus.groovy.runtime.memoize; - -import org.apache.groovy.util.Maps; -import org.junit.Assert; -import org.junit.Test; - -import java.util.HashMap; -import java.util.LinkedHashMap; - -public class SimpleCacheTest { - @Test - public void get() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new LinkedHashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", "Shanghai") - ) - ); - - Assert.assertEquals("Daniel", sc.get("name")); - Assert.assertEquals("Male", sc.get("gender")); - Assert.assertEquals("Shanghai", sc.get("city")); - Assert.assertNull(sc.get("foo")); - } - - @Test - public void put() { - SimpleCache<String, String> sc = new SimpleCache<>(); - - Assert.assertNull(sc.put("name", "Daniel")); - Assert.assertEquals("Daniel", sc.get("name")); - - Assert.assertEquals("Daniel", sc.put("name", "sunlan")); - Assert.assertEquals("sunlan", sc.get("name")); - } - - @Test - public void getAndPut() { - SimpleCache<String, String> sc = new SimpleCache<>(); - - EvictableCache.ValueProvider vp = - new EvictableCache.ValueProvider<String, String>() { - @Override - public String provide(String key) { - return "Chinese"; - } - }; - - Assert.assertEquals("Chinese", sc.getAndPut("language", vp,false)); - Assert.assertNull(sc.get("language")); - - Assert.assertEquals("Chinese", sc.getAndPut("language", vp)); - Assert.assertEquals("Chinese", sc.get("language")); - } - - @Test - public void values() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new LinkedHashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", "Shanghai") - ) - ); - - Assert.assertArrayEquals(new String[] {"Daniel", "Male", "Shanghai"}, sc.values().toArray(new String[0])); - } - - @Test - public void keys() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new LinkedHashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", "Shanghai") - ) - ); - - Assert.assertArrayEquals(new String[] {"name", "gender", "city"}, sc.keys().toArray(new String[0])); - } - - @Test - public void size() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new LinkedHashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", "Shanghai") - ) - ); - - Assert.assertEquals(3, sc.size()); - } - - @Test - public void remove() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new HashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", "Shanghai") - ) - ); - - Assert.assertEquals("Shanghai", sc.remove("city")); - Assert.assertNull(sc.get("city")); - } - - @Test - public void clear() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new LinkedHashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", "Shanghai") - ) - ); - - Assert.assertArrayEquals(new String[] {"Daniel", "Male", "Shanghai"}, sc.values().toArray(new String[0])); - } - - @Test - public void cleanUpNullReferences() { - SimpleCache<String, String> sc = - new SimpleCache<>( - new LinkedHashMap<>( - Maps.of("name", "Daniel", - "gender", "Male", - "city", null) - ) - ); - - sc.cleanUpNullReferences(); - Assert.assertArrayEquals(new String[] {"Daniel", "Male"}, sc.values().toArray(new String[0])); - } -}
