groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject groovy git commit: GROOVY-8604: Cache the parameterized type for better performance(closes #721)
Date Fri, 25 May 2018 01:21:01 GMT
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X b492c874f -> b9ddf6b5c


GROOVY-8604: Cache the parameterized type for better performance(closes #721)

(cherry picked from commit 333dc40)


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

Branch: refs/heads/GROOVY_2_5_X
Commit: b9ddf6b5cf68d9c8504750ac2d857451aa403ff0
Parents: b492c87
Author: sunlan <sunlan@apache.org>
Authored: Fri May 25 09:15:21 2018 +0800
Committer: sunlan <sunlan@apache.org>
Committed: Fri May 25 09:20:56 2018 +0800

----------------------------------------------------------------------
 .../groovy/ast/tools/GenericsUtils.java         | 70 ++++++++++++++++++--
 .../stc/StaticTypeCheckingSupport.java          |  2 +-
 .../stc/StaticTypeCheckingVisitor.java          |  2 +-
 3 files changed, 67 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b9ddf6b5/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 2e8a103..906aab6 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -36,6 +36,8 @@ import org.codehaus.groovy.ast.stmt.EmptyStatement;
 import org.codehaus.groovy.control.CompilationUnit;
 import org.codehaus.groovy.control.ResolveVisitor;
 import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.runtime.memoize.ConcurrentCommonCache;
+import org.codehaus.groovy.runtime.memoize.EvictableCache;
 import org.codehaus.groovy.syntax.ParserException;
 import org.codehaus.groovy.syntax.Reduction;
 
@@ -46,6 +48,7 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicReference;
 
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCorrectedClassNode;
@@ -658,13 +661,27 @@ public class GenericsUtils {
     }
 
     /**
-     * Get the parameterized type by search the whole class hierarchy according to generics
class and actual receiver
+     * Try to get the parameterized type from the cache.
+     * If no cached item found, cache and return the result of {@link #findParameterizedType(ClassNode,
ClassNode)}
+     */
+    public static ClassNode findParameterizedTypeFromCache(final ClassNode genericsClass,
final ClassNode actualType) {
+        return PARAMETERIZED_TYPE_CACHE.getAndPut(new ParameterizedTypeCacheKey(genericsClass,
actualType), new EvictableCache.ValueProvider<ParameterizedTypeCacheKey, ClassNode>()
{
+            @Override
+            public ClassNode provide(ParameterizedTypeCacheKey key) {
+                return findParameterizedType(key.getGenericsClass(), key.getActualType());
+            }
+        });
+    }
+
+    /**
+     * Get the parameterized type by search the whole class hierarchy according to generics
class and actual receiver.
+     * {@link #findParameterizedTypeFromCache(ClassNode, ClassNode)} is strongly recommended
for better performance.
      *
      * @param genericsClass the generics class
-     * @param actualReceiver the actual receiver
+     * @param actualType the actual type
      * @return the parameterized type
      */
-    public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualReceiver)
{
+    public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType)
{
         ClassNode parameterizedType = null;
 
         if (null == genericsClass.getGenericsTypes()) {
@@ -673,8 +690,8 @@ public class GenericsUtils {
 
         GenericsType[] declaringGenericsTypes = genericsClass.getGenericsTypes();
 
-        List<ClassNode> classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualReceiver));
-        classNodeList.add(0, actualReceiver);
+        List<ClassNode> classNodeList = new LinkedList<>(getAllSuperClassesAndInterfaces(actualType));
+        classNodeList.add(0, actualType);
 
         for (ClassNode cn : classNodeList) {
             if (cn == genericsClass) {
@@ -720,4 +737,47 @@ public class GenericsUtils {
 
         return superClassNodeList;
     }
+
+    private static final EvictableCache<ParameterizedTypeCacheKey, ClassNode> PARAMETERIZED_TYPE_CACHE
= new ConcurrentCommonCache<>(128);
+    private static class ParameterizedTypeCacheKey {
+        private ClassNode genericsClass;
+        private ClassNode actualType;
+
+        public ParameterizedTypeCacheKey(ClassNode genericsClass, ClassNode actualType) {
+            this.genericsClass = genericsClass;
+            this.actualType = actualType;
+        }
+
+        public ClassNode getGenericsClass() {
+            return genericsClass;
+        }
+
+        public void setGenericsClass(ClassNode genericsClass) {
+            this.genericsClass = genericsClass;
+        }
+
+        public ClassNode getActualType() {
+            return actualType;
+        }
+
+        public void setActualType(ClassNode actualType) {
+            this.actualType = actualType;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            ParameterizedTypeCacheKey cacheKey = (ParameterizedTypeCacheKey) o;
+
+            return genericsClass == cacheKey.genericsClass &&
+                    actualType == cacheKey.actualType;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(genericsClass, actualType);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/b9ddf6b5/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 5843aa3..d0c6086 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1190,7 +1190,7 @@ public abstract class StaticTypeCheckingSupport {
     }
 
     private static Parameter[] makeRawTypes(Parameter[] params, ClassNode declaringClassForDistance,
ClassNode actualReceiverForDistance) {
-        Map<String, GenericsType> placeholderInfo = GenericsUtils.extractPlaceholders(GenericsUtils.findParameterizedType(declaringClassForDistance,
actualReceiverForDistance));
+        Map<String, GenericsType> placeholderInfo = GenericsUtils.extractPlaceholders(GenericsUtils.findParameterizedTypeFromCache(declaringClassForDistance,
actualReceiverForDistance));
 
         Parameter[] newParam = new Parameter[params.length];
         for (int i = 0; i < params.length; i++) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/b9ddf6b5/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 71d3298..d2371b4 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -616,7 +616,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport
{
                 }
             }
 
-            ClassNode parameterizedType = GenericsUtils.findParameterizedType(fieldNode.getDeclaringClass(),
typeCheckingContext.getEnclosingClassNode());
+            ClassNode parameterizedType = GenericsUtils.findParameterizedTypeFromCache(fieldNode.getDeclaringClass(),
typeCheckingContext.getEnclosingClassNode());
             if (null != parameterizedType) {
                 ClassNode originalType = fieldNode.getOriginType();
                 ClassNode actualType = findActualTypeByPlaceholderName(originalType.getUnresolvedName(),
GenericsUtils.extractPlaceholders(parameterizedType));


Mime
View raw message