Revision: 9867
Author: scheg...@google.com
Date: Fri Mar 18 10:49:05 2011
Log: This change is mostly resources related.
We pre-split path of resources and avoid performing String.split() several
times later.
This gives about 5% speed up in GWT Designer.
Review at http://gwt-code-reviews.appspot.com/1382801
Review by: con...@google.com
http://code.google.com/p/google-web-toolkit/source/detail?r=9867
Added:
/trunk/dev/core/test/com/google/gwt/dev/resource/impl/ResourceTests.java
/trunk/dev/core/test/com/google/gwt/dev/util/StringsTest.java
Modified:
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/DefaultFilters.java
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java
/trunk/dev/core/src/com/google/gwt/dev/util/Strings.java
/trunk/dev/core/test/com/google/gwt/dev/resource/impl/DefaultFiltersTest.java
/trunk/eclipse/samples/Hello/Hello-compModule.launch
=======================================
--- /dev/null
+++
/trunk/dev/core/test/com/google/gwt/dev/resource/impl/ResourceTests.java
Fri Mar 18 10:49:05 2011
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed 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 com.google.gwt.dev.resource.impl;
+
+import com.google.gwt.dev.resource.Resource;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Suite of {@link Resource} related tests.
+ */
+public class ResourceTests {
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Resource tests");
+ suite.addTestSuite(ClassPathEntryTest.class);
+ suite.addTestSuite(DefaultFiltersTest.class);
+ suite.addTestSuite(FileResourceTest.class);
+ suite.addTestSuite(PathPrefixSetTest.class);
+ suite.addTestSuite(ResourceOracleImplRealClasspathTest.class);
+ suite.addTestSuite(ResourceOracleImplTest.class);
+ return suite;
+ }
+
+ private ResourceTests() {
+ }
+}
=======================================
--- /dev/null
+++ /trunk/dev/core/test/com/google/gwt/dev/util/StringsTest.java Fri Mar
18 10:49:05 2011
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed 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 com.google.gwt.dev.util;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+/**
+ * Tests for {@link Strings}.
+ */
+public class StringsTest extends TestCase {
+ /**
+ * Test for {@link Strings#splitPath(String)}.
+ */
+ public void test_splitPath() throws Exception {
+ assertTrue(Arrays.equals(new String[]{"a"}, Strings.splitPath("a")));
+ assertTrue(Arrays.equals(new String[]{"a", "bb", "ccc"},
Strings.splitPath("a/bb/ccc")));
+ assertTrue(Arrays.equals(new String[]{"", "a", "bb"},
Strings.splitPath("/a/bb/")));
+ }
+}
=======================================
---
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/DefaultFilters.java
Tue Feb 1 08:37:27 2011
+++
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/DefaultFilters.java
Fri Mar 18 10:49:05 2011
@@ -53,29 +53,29 @@
public boolean allows(String path) {
return defaultAntIncludes.allows(path) && matches(path);
}
- };
-
+ };
+
private final ResourceFilter defaultFilter = new ResourceFilter() {
public boolean allows(String path) {
return getFileTypeFilter().allows(path)
- && !defaultExcludesPattern.matcher(path).matches();
+ && !isDefaultExcluded(path);
}
};
-
+
private FilterFileType(String suffix) {
this.suffix = suffix;
}
-
+
public ResourceFilter getDefaultFilter() {
return defaultFilter;
}
-
+
/* used when defaultExcludes is false */
public ResourceFilter getFileTypeFilter() {
return justThisFileTypeFilter;
}
-
+
public String getSuffix() {
return suffix;
}
@@ -87,42 +87,50 @@
return path.endsWith(suffix);
}
}
-
- /*
- * list copied from {@link org.apache.tools.ant.DirectoryScanner}
- */
- private static final String DEFAULT_EXCLUDES[] = new String[]{
- // Miscellaneous typical temporary files
- "**/*~", "**/#*#", "**/.#*", "**/%*%", "**/._*",
-
- // CVS
- "**/CVS", "**/CVS/**",
- // to not hit the weird formatting error.
- "**/.cvsignore",
-
- // SCCS
- "**/SCCS", "**/SCCS/**",
-
- // Visual SourceSafe
- "**/vssver.scc",
-
- // Subversion
- "**/.svn", "**/.svn/**",
-
- // Mac
- "**/.DS_Store",};
// \w (word character), ., $, /, -, *, ~, #, %
private static final Pattern antPattern =
Pattern.compile("^[\\w\\.\\$/\\-\\*~#%]*$");
- private static final Pattern defaultExcludesPattern =
getPatternFromAntStrings(DEFAULT_EXCLUDES);
-
// accepts all but paths starting with '/'. Default include list is '**'
private static final ResourceFilter defaultAntIncludes = new
ResourceFilter() {
public boolean allows(String path) {
return path.charAt(0) != '/';
}
};
+
+ /**
+ * @return <code>true</code> if given path should be excluded from
resources.
+ */
+ private static boolean isDefaultExcluded(String path) {
+ // CVS
+ if (path.endsWith("/CVS") || path.contains("/CVS/") ||
path.startsWith("CVS/")
+ || path.endsWith("/.cvsignore")) {
+ return true;
+ }
+ // Subversion
+ if (path.endsWith("/.svn") || path.contains("/.svn/") ||
path.startsWith(".svn/")
+ || path.endsWith("/.svnignore")) {
+ return true;
+ }
+ // Git
+ if (path.endsWith("/.git") || path.contains("/.git/") ||
path.startsWith(".git/")
+ || path.endsWith("/.gitignore")) {
+ return true;
+ }
+ // SCCS
+ if (path.endsWith("/SCCS") || path.contains("/SCCS/")) {
+ return true;
+ }
+ // Visual SourceSafe
+ if (path.endsWith("/vssver.scc")) {
+ return true;
+ }
+ // Mac
+ if (path.endsWith("/.DS_Store")) {
+ return true;
+ }
+ return false;
+ }
/**
* Returns a pattern string that can be passed in Java
Pattern.compile(..).
@@ -254,20 +262,6 @@
}
return answer;
}
-
- private static Pattern getPatternFromAntStrings(String... antPatterns) {
- String patternStrings[] = new String[antPatterns.length];
- int count = 0;
- for (String antPatternString : antPatterns) {
- String patternString = getPatternFromAntPattern(antPatternString);
- if (patternString == null) {
- throw new RuntimeException("Unable to convert " + antPatternString
- + " to java code");
- }
- patternStrings[count++] = patternString;
- }
- return getPatternFromStrings(patternStrings);
- }
private static Pattern getPatternFromStrings(String... patterns) {
StringBuffer entirePattern = new StringBuffer("^");
@@ -310,7 +304,7 @@
return getCustomFilter(includeList, excludeList, skipList,
defaultExcludes,
caseSensitive, FilterFileType.RESOURCE_FILES);
}
-
+
/**
* Return a customResourceFiter that handles all the argument. If unable
to
* create a customResourceFilter that handles the arguments, catchAll is
used
@@ -349,7 +343,7 @@
return false;
}
if (defaultExcludes) {
- return !defaultExcludesPattern.matcher(path).matches();
+ return !isDefaultExcluded(path);
}
return true;
}
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java
Thu Sep 23 06:33:21 2010
+++ /trunk/dev/core/src/com/google/gwt/dev/resource/impl/PathPrefixSet.java
Fri Mar 18 10:49:05 2011
@@ -220,6 +220,14 @@
* match or the most specific prefix excludes the resource.
*/
public PathPrefix includesResource(String resourceAbstractPathName) {
+ String[] parts = resourceAbstractPathName.split("/");
+ return includesResource(resourceAbstractPathName, parts);
+ }
+
+ /**
+ * Implementation of {@link #includesDirectory(String)}.
+ */
+ public PathPrefix includesResource(String resourceAbstractPathName,
String[] parts) {
/*
* Algorithm: dive down the package hierarchy looking for the most
specific
* package that applies to this resource. The filter of the most
specific
@@ -234,7 +242,7 @@
PathPrefix mostSpecificPrefix = rootTrieNode.getPathPrefix();
// Walk all but the last path part, which is assumed to be a file name.
- for (String part : resourceAbstractPathName.split("/")) {
+ for (String part : parts) {
assert (!"".equals(part));
TrieNode childNode = currentNode.findChild(part);
if (childNode != null) {
=======================================
---
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
Fri Jan 7 09:43:50 2011
+++
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
Fri Mar 18 10:49:05 2011
@@ -28,7 +28,6 @@
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
import java.util.zip.ZipFile;
/**
@@ -78,7 +77,7 @@
private final ZipFile zipFile;
- public ZipFileClassPathEntry(File zipFile) throws ZipException,
IOException {
+ public ZipFileClassPathEntry(File zipFile) throws IOException {
assert zipFile.isAbsolute();
this.zipFile = new ZipFile(zipFile);
this.location = zipFile.toURI().toString();
@@ -147,8 +146,9 @@
Map<AbstractResource, PathPrefix> results = new
IdentityHashMap<AbstractResource, PathPrefix>();
for (ZipFileResource r : allZipFileResources) {
String path = r.getPath();
+ String[] pathParts = r.getPathParts();
PathPrefix prefix = null;
- if ((prefix = pathPrefixSet.includesResource(path)) != null) {
+ if ((prefix = pathPrefixSet.includesResource(path, pathParts)) !=
null) {
Messages.INCLUDING_RESOURCE.log(logger, path, null);
results.put(r, prefix);
} else {
=======================================
---
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java
Tue Oct 5 11:03:13 2010
+++
/trunk/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileResource.java
Fri Mar 18 10:49:05 2011
@@ -16,6 +16,7 @@
package com.google.gwt.dev.resource.impl;
import com.google.gwt.dev.util.StringInterner;
+import com.google.gwt.dev.util.Strings;
import java.io.IOException;
import java.io.InputStream;
@@ -28,12 +29,13 @@
private final ZipFileClassPathEntry classPathEntry;
private final String path;
+ private final String[] pathParts;
private long lastModified;
- public ZipFileResource(ZipFileClassPathEntry classPathEntry, String path,
- long lastModified) {
+ public ZipFileResource(ZipFileClassPathEntry classPathEntry, String
path, long lastModified) {
this.classPathEntry = classPathEntry;
this.path = StringInterner.get().intern(path);
+ this.pathParts = Strings.splitPath(path);
this.lastModified = lastModified;
}
@@ -58,6 +60,13 @@
public String getPath() {
return path;
}
+
+ /**
+ * @return components of {@link #getPath()}.
+ */
+ public String[] getPathParts() {
+ return pathParts;
+ }
@Override
public InputStream openContents() {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/util/Strings.java Tue Mar 9
10:54:56 2010
+++ /trunk/dev/core/src/com/google/gwt/dev/util/Strings.java Fri Mar 18
10:49:05 2011
@@ -15,23 +15,47 @@
*/
package com.google.gwt.dev.util;
+import com.google.gwt.thirdparty.guava.common.collect.Lists;
+
+import java.util.ArrayList;
+
/**
* String manipulation utilities.
*/
public class Strings {
+
/**
- * Join strings inserting separator between them.
+ * Join strings inserting separator between them.
*/
public static String join(String[] strings, String separator) {
StringBuffer result = new StringBuffer();
-
+
for (String s : strings) {
if (result.length() != 0) {
result.append(separator);
}
result.append(s);
}
-
+
return result.toString();
}
-}
+
+ /**
+ * @return the path components, result of splitting by "/".
+ */
+ public static String[] splitPath(String path) {
+ ArrayList<String> result = Lists.newArrayList();
+ int length = path.length();
+ int begin = 0;
+ for (int i = 0; i < length; i++) {
+ if (path.charAt(i) == '/') {
+ result.add(path.substring(begin, i));
+ begin = i + 1;
+ }
+ }
+ if (begin < length) {
+ result.add(path.substring(begin));
+ }
+ return result.toArray(new String[result.size()]);
+ }
+}
=======================================
---
/trunk/dev/core/test/com/google/gwt/dev/resource/impl/DefaultFiltersTest.java
Tue Feb 1 08:37:27 2011
+++
/trunk/dev/core/test/com/google/gwt/dev/resource/impl/DefaultFiltersTest.java
Fri Mar 18 10:49:05 2011
@@ -111,9 +111,9 @@
static class BasicPaths {
String baseIncluded[] = {
- "foo", "/foo", "foo/bar", "/foo/bar", "/foo/bar", "/foo$/$", "/foo-_",
- "123FOO123", "cvs", "cvs/cvs/svn", ".foo_bar$", "foo/asvn"};
- String baseExcluded[] =
{"foo/CVS/bar", "foo/.svn/bar", "foo/SCCS/bar",};
+ "foo", "/foo", "foo/bar", "/foo/bar", "/foo/bar", "/foo$/$", "/foo-_",
"123FOO123", "cvs",
+ "cvs/cvs/svn", ".foo_bar$", "foo/asvn"};
+ String baseExcluded[] =
{"foo/CVS/bar", "CVS/bar", "foo/.svn/bar", ".svn/bar", "foo/SCCS/bar",};
String baseSuffixExcluded[] = {
"foo/.cvsignore", "foo/CVS", "foo/.svn", "foo/SCCS",
"foo/bar/vssver.scc", "/foo/bar/.DS_Store"};
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors