You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by cc...@apache.org on 2018/05/23 19:30:36 UTC

[1/9] groovy git commit: Cache external class lookup

Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_6_X 1310dadc8 -> 1682f78aa


Cache external class lookup


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

Branch: refs/heads/GROOVY_2_6_X
Commit: 1682f78aaec5463e13c9ea9a25127110747855c9
Parents: afbc493
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 12:12:21 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../groovy/tools/groovydoc/SimpleGroovyClassDoc.java | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/1682f78a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
index 3522fa1..d9f40a5 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
@@ -32,6 +32,7 @@ import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -80,6 +81,7 @@ public class SimpleGroovyClassDoc extends SimpleGroovyAbstractableElementDoc imp
     private final List<GroovyClassDoc> interfaceClasses;
     private final List<GroovyClassDoc> nested;
     private final List<LinkArgument> links;
+    private final Map<String, Class<?>> resolvedExternalClassesCache;
     private GroovyClassDoc superClass;
     private GroovyClassDoc outer;
     private String superClassName;
@@ -101,6 +103,7 @@ public class SimpleGroovyClassDoc extends SimpleGroovyAbstractableElementDoc imp
         interfaceNames = new ArrayList<String>();
         interfaceClasses = new ArrayList<GroovyClassDoc>();
         nested = new ArrayList<GroovyClassDoc>();
+        resolvedExternalClassesCache = new HashMap<String, Class<?>>();
     }
 
     public SimpleGroovyClassDoc(List<String> importedClassesAndPackages, Map<String, String> aliases, String name) {
@@ -667,6 +670,18 @@ public class SimpleGroovyClassDoc extends SimpleGroovyAbstractableElementDoc imp
 
     private Class resolveExternalClassFromImport(String name) {
         if (isPrimitiveType(name)) return null;
+        Class<?> clazz = resolvedExternalClassesCache.get(name);
+        if (clazz == null) {
+            if (resolvedExternalClassesCache.containsKey(name)) {
+                return null;
+            }
+            clazz = doResolveExternalClassFromImport(name);
+            resolvedExternalClassesCache.put(name, clazz);
+        }
+        return clazz;
+    }
+
+    private Class doResolveExternalClassFromImport(final String name) {
         for (String importName : importedClassesAndPackages) {
             String candidate = null;
             if (importName.endsWith("/" + name)) {


[9/9] groovy git commit: Don't use exception for control flow

Posted by cc...@apache.org.
Don't use exception for control flow

It's extremely slow, as we generate tons of stacktraces for nothing!


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

Branch: refs/heads/GROOVY_2_6_X
Commit: 3b6fd8c0495ce891a45dce44235d2cea23243c53
Parents: e9cb3af
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 11:42:42 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../org/codehaus/groovy/antlr/GroovySourceAST.java | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/3b6fd8c0/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java b/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java
index 80da241..1f0d8b5 100644
--- a/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java
+++ b/src/main/java/org/codehaus/groovy/antlr/GroovySourceAST.java
@@ -62,7 +62,7 @@ public class GroovySourceAST extends CommonAST implements Comparable, SourceInfo
         if (t instanceof SourceInfo) {
             SourceInfo info = (SourceInfo) t;
             lineLast = info.getLineLast();
-            colLast  = info.getColumnLast(); 
+            colLast  = info.getColumnLast();
         }
     }
 
@@ -140,17 +140,16 @@ public class GroovySourceAST extends CommonAST implements Comparable, SourceInfo
     }
 
     public GroovySourceAST childAt(int position) {
-        List list = new ArrayList();
+        int cur = 0;
         AST child = this.getFirstChild();
-        while (child != null) {
-            list.add(child);
+        while (child != null && cur <= position) {
+            if (cur == position) {
+                return (GroovySourceAST) child;
+            }
+            cur++;
             child = child.getNextSibling();
         }
-        try {
-            return (GroovySourceAST)list.get(position);
-        } catch (IndexOutOfBoundsException e) {
-            return null;
-        }
+        return null;
     }
 
     public GroovySourceAST childOfType(int type) {


[4/9] groovy git commit: Cache class resolution

Posted by cc...@apache.org.
Cache class resolution

As soon as we have a project with a reasonable size, we spend a large
amount of time resolving the same classes again and again. This commit
introduces a (poor man's) cache to avoid the same lookups. It's not an
attempt to make Groovydoc better, it's just a patch to make it not so
slow.


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

Branch: refs/heads/GROOVY_2_6_X
Commit: 85a4c5a9169c0c4fbaaa77905dbad8981d09b632
Parents: 1310dad
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 08:34:10 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../groovy/groovydoc/GroovyRootDoc.java         |  2 ++
 .../tools/groovydoc/SimpleGroovyClassDoc.java   | 11 +++++++++
 .../tools/groovydoc/SimpleGroovyRootDoc.java    | 24 +++++++++++++++++++-
 3 files changed, 36 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/85a4c5a9/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyRootDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyRootDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyRootDoc.java
index f18fd53..1e34c10 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyRootDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/groovydoc/GroovyRootDoc.java
@@ -35,4 +35,6 @@ public interface GroovyRootDoc extends GroovyDoc, GroovyDocErrorReporter {
     GroovyPackageDoc[] specifiedPackages();
 
     Map<String, GroovyClassDoc> getVisibleClasses(List importedClassesAndPackages);
+
+    Map<String, GroovyClassDoc> getResolvedClasses();
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/85a4c5a9/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
index b5be4d7..3522fa1 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyClassDoc.java
@@ -547,6 +547,17 @@ public class SimpleGroovyClassDoc extends SimpleGroovyAbstractableElementDoc imp
 
     private GroovyClassDoc resolveClass(GroovyRootDoc rootDoc, String name) {
         if (isPrimitiveType(name)) return null;
+        Map<String, GroovyClassDoc> resolvedClasses = rootDoc.getResolvedClasses();
+        GroovyClassDoc groovyClassDoc = resolvedClasses.get(name);
+        if (groovyClassDoc != null) {
+            return groovyClassDoc;
+        }
+        groovyClassDoc = doResolveClass(rootDoc, name);
+        resolvedClasses.put(name, groovyClassDoc);
+        return groovyClassDoc;
+    }
+
+    private GroovyClassDoc doResolveClass(final GroovyRootDoc rootDoc, final String name) {
         if (name.endsWith("[]")) {
             GroovyClassDoc componentClass = resolveClass(rootDoc, name.substring(0, name.length() - 2));
             if (componentClass != null) return new ArrayClassDocWrapper(componentClass);

http://git-wip-us.apache.org/repos/asf/groovy/blob/85a4c5a9/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
index eeffd16..6bb4940 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
@@ -24,21 +24,29 @@ import org.codehaus.groovy.groovydoc.GroovyRootDoc;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDoc {
+    private final static Pattern EQUIVALENT_PACKAGE_IMPORT = Pattern.compile("[^/]+$");
+
     private final Map<String, GroovyPackageDoc> packageDocs;
     private List<GroovyPackageDoc> packageDocValues = null;
     private final Map<String, GroovyClassDoc> classDocs;
+    private final Map<String, String> equivalentPackageImports;
     private List<GroovyClassDoc> classDocValues = null;
+    private final Map<String, GroovyClassDoc> cachedResolvedClasses = new HashMap<String, GroovyClassDoc>();
+
     private String description = "";
 
     public SimpleGroovyRootDoc(String name) {
         super(name);
         packageDocs = new LinkedHashMap<String, GroovyPackageDoc>();
         classDocs = new LinkedHashMap<String, GroovyClassDoc>();
+        equivalentPackageImports = new HashMap<String, String>();
     }
 
     public GroovyClassDoc classNamed(GroovyClassDoc groovyClassDoc, String name) {
@@ -124,7 +132,7 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
         Map<String, GroovyClassDoc> visibleClasses = new LinkedHashMap<String, GroovyClassDoc>();
         for (Map.Entry<String, GroovyClassDoc> entry : classDocs.entrySet()) {
             String fullClassName = entry.getKey();
-            String equivalentPackageImport = fullClassName.replaceAll("[^/]+$", "*");
+            String equivalentPackageImport = findEquivalentPackageImport(fullClassName);
             if (importedClassesAndPackages.contains(fullClassName) ||
                     importedClassesAndPackages.contains(equivalentPackageImport)) {
                 GroovyClassDoc classDoc = entry.getValue();
@@ -134,6 +142,20 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
         return visibleClasses;
     }
 
+    private String findEquivalentPackageImport(String fullClassName) {
+        String eq = equivalentPackageImports.get(fullClassName);
+        if (eq == null) {
+            eq = EQUIVALENT_PACKAGE_IMPORT.matcher(fullClassName).replaceAll("*");
+            equivalentPackageImports.put(fullClassName, eq);
+        }
+        return eq;
+    }
+
+    @Override
+    public Map<String, GroovyClassDoc> getResolvedClasses() {
+        return cachedResolvedClasses;
+    }
+
     // GroovyDocErrorReporter interface
     public void printError(String arg0) {/*todo*/}
 


[3/9] groovy git commit: Perform direct lookup in maps

Posted by cc...@apache.org.
Perform direct lookup in maps

Why the h... we were iterating over the map to check each entry
is beyond my understanding.


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

Branch: refs/heads/GROOVY_2_6_X
Commit: b0f422350aa1edf975a9b340475c9fe61c929b81
Parents: ac17236
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 09:49:38 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../groovy/tools/groovydoc/SimpleGroovyRootDoc.java      | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/b0f42235/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
index 6bb4940..661ff92 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
@@ -50,10 +50,13 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
     }
 
     public GroovyClassDoc classNamed(GroovyClassDoc groovyClassDoc, String name) {
+        GroovyClassDoc doc = classDocs.get(name);
+        if (doc != null) {
+            return doc;
+        }
         // look for full match or match excluding package
         for (Map.Entry<String, GroovyClassDoc> entry : classDocs.entrySet()) {
             String key = entry.getKey();
-            if (key.equals(name)) return entry.getValue();
             int lastSlashIdx = key.lastIndexOf('/');
             if (lastSlashIdx > 0) {
                 String shortKey = key.substring(lastSlashIdx + 1);
@@ -71,11 +74,7 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
     }
 
     public GroovyClassDoc classNamedExact(String name) {
-        for (Map.Entry<String, GroovyClassDoc> entry : classDocs.entrySet()) {
-            String key = entry.getKey();
-            if (key.equals(name)) return entry.getValue();
-        }
-        return null;
+        return classDocs.get(name);
     }
 
     public void setDescription(String description) {


[8/9] groovy git commit: Precompile some regular expressions

Posted by cc...@apache.org.
Precompile some regular expressions


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

Branch: refs/heads/GROOVY_2_6_X
Commit: afbc4936af94874ceefdb80ef115697f099a75ca
Parents: ea645a0
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 12:03:18 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java   | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/afbc4936/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
index 8dd1d9c..cb39402 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyDoc.java
@@ -32,6 +32,8 @@ import java.util.regex.Pattern;
 public class SimpleGroovyDoc implements GroovyDoc, GroovyTokenTypes {
     private static final Pattern TAG2_PATTERN = Pattern.compile("(?s)([a-z]+)\\s+(.*)");
     private static final Pattern TAG3_PATTERN = Pattern.compile("(?s)([a-z]+)\\s+(\\S*)\\s+(.*)");
+    private static final Pattern RAW_COMMENT_PATTERN = Pattern.compile("\"(?s).*?\\\\*\\\\s*@\"");
+    private static final Pattern TRIMMED_COMMENT_PATTERN = Pattern.compile("(?m)^\\s*\\*\\s*([^*]*)$");
     private final String name;
     private String commentText = null;
     private String rawCommentText = "";
@@ -84,9 +86,9 @@ public class SimpleGroovyDoc implements GroovyDoc, GroovyTokenTypes {
     }
 
     private void calculateTags(String rawCommentText) {
-        String trimmed = rawCommentText.replaceFirst("(?s).*?\\*\\s*@", "@");
+        String trimmed = RAW_COMMENT_PATTERN.matcher(rawCommentText).replaceFirst("@");
         if (trimmed.equals(rawCommentText)) return;
-        String cleaned = trimmed.replaceAll("(?m)^\\s*\\*\\s*([^*]*)$", "$1").trim();
+        String cleaned = TRIMMED_COMMENT_PATTERN.matcher(trimmed).replaceAll("$1").trim();
         String[] split = cleaned.split("(?m)^@");
         List<GroovyTag> result = new ArrayList<GroovyTag>();
         for (String s : split) {


[2/9] groovy git commit: Cache classNamed lookups

Posted by cc...@apache.org.
Cache classNamed lookups

The calls to `substring` are pretty expensive and done again and again
on the same classes. This is extremely inefficient, so this commit adds
an adhoc cache for this. Note that the relativeness to GroovyClassDoc
seems related to a poorly designed modeled, it can certainly be even
faster.


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

Branch: refs/heads/GROOVY_2_6_X
Commit: ea645a0e0026baa81d313bd14a8754f49148249b
Parents: 3b6fd8c
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 11:58:11 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../tools/groovydoc/SimpleGroovyRootDoc.java    | 100 +++++++++++++++----
 1 file changed, 82 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ea645a0e/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
index 3748907..d88fca3 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
@@ -39,6 +39,7 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
     private final Map<String, String> equivalentPackageImports;
     private List<GroovyClassDoc> classDocValues = null;
     private final Map<String, GroovyClassDoc> cachedResolvedClasses = new HashMap<String, GroovyClassDoc>();
+    private final ClassNamedCache classNamedCache;
 
     private String description = "";
 
@@ -47,6 +48,7 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
         packageDocs = new LinkedHashMap<String, GroovyPackageDoc>();
         classDocs = new LinkedHashMap<String, GroovyClassDoc>();
         equivalentPackageImports = new HashMap<String, String>();
+        classNamedCache = new ClassNamedCache(classDocs);
     }
 
     public GroovyClassDoc classNamed(GroovyClassDoc groovyClassDoc, String name) {
@@ -54,24 +56,7 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
         if (doc != null) {
             return doc;
         }
-        // look for full match or match excluding package
-        String fullPathName = groovyClassDoc != null ? groovyClassDoc.getFullPathName() : null;
-        boolean hasPackage = (fullPathName != null && fullPathName.lastIndexOf('/') > 0);
-        if (hasPackage) {
-            fullPathName = fullPathName.substring(0, fullPathName.lastIndexOf('/'));
-        }
-
-        for (Map.Entry<String, GroovyClassDoc> entry : classDocs.entrySet()) {
-            String key = entry.getKey();
-            int lastSlashIdx = key.lastIndexOf('/');
-            if (lastSlashIdx > 0) {
-                String shortKey = key.substring(lastSlashIdx + 1);
-                if (shortKey.equals(name) && (!hasPackage || key.startsWith(fullPathName))) {
-                    return entry.getValue();
-                }
-            }
-        }
-        return null;
+        return classNamedCache.search(groovyClassDoc, name);
     }
 
     public GroovyClassDoc classNamedExact(String name) {
@@ -175,4 +160,83 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
 
     }
 
+    private static class ClassNamedCache {
+        private final Map<String, GroovyClassDoc> classDocs;
+        private final Map<Entry, GroovyClassDoc> store = new HashMap<>();
+
+        private ClassNamedCache(final Map<String, GroovyClassDoc> classDocs) {
+            this.classDocs = classDocs;
+        }
+
+        public GroovyClassDoc search(GroovyClassDoc groovyClassDoc, String name) {
+            Entry entry = new Entry(groovyClassDoc, name);
+            GroovyClassDoc result = store.get(entry);
+            if (result == null) {
+                if (store.containsKey(entry)) {
+                    return null;
+                }
+                result = performLookup(groovyClassDoc, name);
+                store.put(entry, result);
+            }
+            return result;
+        }
+
+        private GroovyClassDoc performLookup(GroovyClassDoc groovyClassDoc, String name) {
+            // look for full match or match excluding package
+            String fullPathName = groovyClassDoc != null ? groovyClassDoc.getFullPathName() : null;
+            boolean hasPackage = (fullPathName != null && fullPathName.lastIndexOf('/') > 0);
+            if (hasPackage) {
+                fullPathName = fullPathName.substring(0, fullPathName.lastIndexOf('/'));
+            }
+
+            for (Map.Entry<String, GroovyClassDoc> entry : classDocs.entrySet()) {
+                String key = entry.getKey();
+                int lastSlashIdx = key.lastIndexOf('/');
+                if (lastSlashIdx > 0) {
+                    String shortKey = key.substring(lastSlashIdx + 1);
+                    if (shortKey.equals(name) && (!hasPackage || key.startsWith(fullPathName))) {
+                        GroovyClassDoc value = entry.getValue();
+                        return value;
+                    }
+                }
+            }
+            return null;
+        }
+
+        private static class Entry {
+            private final GroovyClassDoc groovyClass;
+            private final String name;
+            private final int hashCode;
+
+            private Entry(final GroovyClassDoc groovyClass, final String name) {
+                this.groovyClass = groovyClass;
+                this.name = name;
+                this.hashCode = computeHash();
+            }
+
+            @Override
+            public boolean equals(final Object o) {
+                if (this == o) return true;
+                if (o == null || getClass() != o.getClass()) return false;
+
+                final Entry entry = (Entry) o;
+
+                if (groovyClass != null ? !groovyClass.equals(entry.groovyClass) : entry.groovyClass != null)
+                    return false;
+                return name.equals(entry.name);
+            }
+
+            private int computeHash() {
+                int result = groovyClass != null ? groovyClass.hashCode() : 0;
+                result = 31 * result + name.hashCode();
+                return result;
+            }
+
+            @Override
+            public int hashCode() {
+                return hashCode;
+            }
+        }
+    }
+
 }


[6/9] groovy git commit: Use a reasonable size buffer for generated docs

Posted by cc...@apache.org.
Use a reasonable size buffer for generated docs

The default buffer is a 16(!) characters string. Most of the groovydoc
files we generate are over 10k, so this commit adds a reasonable size
buffer for templates, which avoids a lot of buffer resizes.


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

Branch: refs/heads/GROOVY_2_6_X
Commit: ac17236fc1a97267cdb7a0a1e1475567bfa406f7
Parents: 85a4c5a
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 08:35:41 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../groovy/tools/groovydoc/GroovyDocTemplateEngine.java       | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/ac17236f/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocTemplateEngine.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocTemplateEngine.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocTemplateEngine.java
index ce63ed5..052f29c 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocTemplateEngine.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/GroovyDocTemplateEngine.java
@@ -31,6 +31,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.StringWriter;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
@@ -85,7 +86,7 @@ public class GroovyDocTemplateEngine {
             Map<String, Object> binding = new LinkedHashMap<String, Object>();
             binding.put("classDoc", classDoc);
             binding.put("props", properties);
-            templateWithBindingApplied = t.make(binding).toString();
+            templateWithBindingApplied = t.make(binding).writeTo(reasonableSizeWriter()).toString();
         } catch (Exception e) {
             System.out.println("Error processing class template for: " + classDoc.getFullPathName());
             e.printStackTrace();
@@ -93,6 +94,10 @@ public class GroovyDocTemplateEngine {
         return templateWithBindingApplied;
     }
 
+    private static StringWriter reasonableSizeWriter() {
+        return new StringWriter(65536);
+    }
+
     String applyPackageTemplate(String template, GroovyPackageDoc packageDoc) {
         String templateWithBindingApplied = "";
         try {


[5/9] groovy git commit: Implement a bit smarter lookup

Posted by cc...@apache.org.
Implement a bit smarter lookup

The code isn't really clear what the inputs/outputs are, so it's
just reordering things to make it faster.


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

Branch: refs/heads/GROOVY_2_6_X
Commit: cdca9615bfff293d2e37d3447b8787370d214cd7
Parents: b0f4223
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 09:59:59 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../groovy/tools/groovydoc/SimpleGroovyRootDoc.java      | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/cdca9615/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
----------------------------------------------------------------------
diff --git a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
index 661ff92..3748907 100644
--- a/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
+++ b/subprojects/groovy-groovydoc/src/main/java/org/codehaus/groovy/tools/groovydoc/SimpleGroovyRootDoc.java
@@ -55,16 +55,17 @@ public class SimpleGroovyRootDoc extends SimpleGroovyDoc implements GroovyRootDo
             return doc;
         }
         // look for full match or match excluding package
+        String fullPathName = groovyClassDoc != null ? groovyClassDoc.getFullPathName() : null;
+        boolean hasPackage = (fullPathName != null && fullPathName.lastIndexOf('/') > 0);
+        if (hasPackage) {
+            fullPathName = fullPathName.substring(0, fullPathName.lastIndexOf('/'));
+        }
+
         for (Map.Entry<String, GroovyClassDoc> entry : classDocs.entrySet()) {
             String key = entry.getKey();
             int lastSlashIdx = key.lastIndexOf('/');
             if (lastSlashIdx > 0) {
                 String shortKey = key.substring(lastSlashIdx + 1);
-                String fullPathName = groovyClassDoc != null ? groovyClassDoc.getFullPathName() : null;
-
-                boolean hasPackage = (fullPathName != null && fullPathName.lastIndexOf('/') > 0);
-                if (hasPackage) fullPathName = fullPathName.substring(0, fullPathName.lastIndexOf('/'));
-
                 if (shortKey.equals(name) && (!hasPackage || key.startsWith(fullPathName))) {
                     return entry.getValue();
                 }


[7/9] groovy git commit: Optimize StringBuilder#leftShift for GString case

Posted by cc...@apache.org.
Optimize StringBuilder#leftShift for GString case


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

Branch: refs/heads/GROOVY_2_6_X
Commit: e9cb3afcab73657dd68d3c25a13255808b01233d
Parents: cdca961
Author: Cedric Champeau <cc...@apache.org>
Authored: Wed May 23 11:03:47 2018 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Wed May 23 21:30:26 2018 +0200

----------------------------------------------------------------------
 .../groovy/vmplugin/v5/PluginDefaultGroovyMethods.java   | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/e9cb3afc/src/main/java/org/codehaus/groovy/vmplugin/v5/PluginDefaultGroovyMethods.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v5/PluginDefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/vmplugin/v5/PluginDefaultGroovyMethods.java
index 208e815..39a5e71 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v5/PluginDefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v5/PluginDefaultGroovyMethods.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.vmplugin.v5;
 
 import groovy.lang.EmptyRange;
+import groovy.lang.GString;
 import groovy.lang.IntRange;
 import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport;
 import org.codehaus.groovy.runtime.InvokerHelper;
@@ -96,10 +97,16 @@ public class PluginDefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @return the StringBuilder on which this operation was invoked
      */
     public static StringBuilder leftShift(StringBuilder self, Object value) {
-        if (value instanceof CharSequence)
+        if (value instanceof GString) {
+            // Force the conversion of the GString to string now, or appending
+            // is going to be extremely expensive, due to calls to GString#charAt,
+            // which is going to re-evaluate the GString for each character!
+            return self.append(value.toString());
+        } else if (value instanceof CharSequence) {
             return self.append((CharSequence)value);
-        else
+        } else {
             return self.append(value);
+        }
     }
 
     /**