Reviewers: conroy,

Description:
Using cached ZipFileClassPathEntry objects.

While this does not give benefits for DevMode, which parses jar files
only once, GWT Designer does this many times.
This gives about 15% speed up in GWT Designer.

Initial.
-------------
Parsing...done: 4775
refresh: 296
palette: 114
Parsing...done: 2445
refresh: 274
palette: 38
Parsing...done: 2396
refresh: 272
palette: 37

Cache ZipFileClassPathEntry
-------------
Parsing...done: 4299
refresh: 304
palette: 116
Parsing...done: 2161
refresh: 277
palette: 41
Parsing...done: 2087
refresh: 270
palette: 38


Please review this at http://gwt-code-reviews.appspot.com/1388803/

Affected files:
  M dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
  M dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
M dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java M dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java


Index: dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java
===================================================================
--- dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java (revision 9867) +++ dev/core/src/com/google/gwt/dev/resource/impl/ResourceOracleImpl.java (working copy)
@@ -156,14 +156,14 @@
       if (f.isDirectory()) {
         return new DirectoryClassPathEntry(f);
       } else if (f.isFile() && lowerCaseFileName.endsWith(".jar")) {
-        return new ZipFileClassPathEntry(f);
+        return ZipFileClassPathEntry.get(f);
       } else if (f.isFile() && lowerCaseFileName.endsWith(".zip")) {
-        return new ZipFileClassPathEntry(f);
+        return ZipFileClassPathEntry.get(f);
       } else {
         // It's a file ending in neither jar nor zip, speculatively try to
         // open as jar/zip anyway.
         try {
-          return new ZipFileClassPathEntry(f);
+          return ZipFileClassPathEntry.get(f);
         } catch (Exception ignored) {
         }
         logger.log(TreeLogger.TRACE, "Unexpected entry in classpath; " + f
Index: dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
===================================================================
--- dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java (revision 9867) +++ dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java (working copy)
@@ -21,6 +21,9 @@
 import com.google.gwt.dev.util.collect.IdentityMaps;
 import com.google.gwt.dev.util.collect.Sets;
 import com.google.gwt.dev.util.msg.Message1String;
+
+import org.apache.commons.collections.map.AbstractReferenceMap;
+import org.apache.commons.collections.map.ReferenceMap;

 import java.io.File;
 import java.io.IOException;
@@ -65,6 +68,37 @@
       this.cachedAnswers = cachedAnswers;
     }
   }
+
+  private static class ZipFileCachedEntry {
+    private final long lastModified;
+    private final ZipFileClassPathEntry entry;
+    public ZipFileCachedEntry(File zipFile, ZipFileClassPathEntry entry) {
+      this.lastModified = zipFile.lastModified();
+      this.entry = entry;
+    }
+    public boolean isStale(File zipFile) {
+      return lastModified != zipFile.lastModified();
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+ private static final Map<String, ZipFileCachedEntry> entryCache = new ReferenceMap(
+      AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);
+
+  /**
+ * @return the {@link ZipFileClassPathEntry} instance for given jar or zip
+   *         file, may be shared with other users.
+   */
+ public static ZipFileClassPathEntry get(File zipFile) throws IOException {
+    String location = zipFile.toURI().toString();
+    ZipFileCachedEntry cachedEntry = entryCache.get(location);
+    if (cachedEntry == null || cachedEntry.isStale(zipFile)) {
+      ZipFileClassPathEntry entry = new ZipFileClassPathEntry(zipFile);
+      cachedEntry = new ZipFileCachedEntry(zipFile, entry);
+      entryCache.put(location, cachedEntry);
+    }
+    return cachedEntry.entry;
+  }

   private Set<ZipFileResource> allZipFileResources;

@@ -77,7 +111,7 @@

   private final ZipFile zipFile;

-  public ZipFileClassPathEntry(File zipFile) throws IOException {
+  private ZipFileClassPathEntry(File zipFile) throws IOException {
     assert zipFile.isAbsolute();
     this.zipFile = new ZipFile(zipFile);
     this.location = zipFile.toURI().toString();
Index: dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java
===================================================================
--- dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java (revision 9867) +++ dev/core/test/com/google/gwt/dev/resource/impl/AbstractResourceOrientedTestBase.java (working copy)
@@ -193,12 +193,12 @@
   protected ClassPathEntry getClassPathEntry1AsJar() throws IOException,
       URISyntaxException {
File file = findFile("com/google/gwt/dev/resource/impl/testdata/cpe1.jar");
-    return new ExcludeSvnClassPathEntry(new ZipFileClassPathEntry(file));
+    return new ExcludeSvnClassPathEntry(ZipFileClassPathEntry.get(file));
   }

protected ClassPathEntry getClassPathEntry1AsZip() throws IOException, URISyntaxException { File file = findFile("com/google/gwt/dev/resource/impl/testdata/cpe1.zip");
-    return new ExcludeSvnClassPathEntry(new ZipFileClassPathEntry(file));
+    return new ExcludeSvnClassPathEntry(ZipFileClassPathEntry.get(file));
   }

   protected ClassPathEntry getClassPathEntry1AsMock() {
@@ -214,12 +214,12 @@
protected ClassPathEntry getClassPathEntry2AsJar() throws URISyntaxException,
       IOException {
File file = findFile("com/google/gwt/dev/resource/impl/testdata/cpe2.jar");
-    return new ExcludeSvnClassPathEntry(new ZipFileClassPathEntry(file));
+    return new ExcludeSvnClassPathEntry(ZipFileClassPathEntry.get(file));
   }

protected ClassPathEntry getClassPathEntry2AsZip() throws URISyntaxException, IOException { File file = findFile("com/google/gwt/dev/resource/impl/testdata/cpe2.zip");
-    return new ExcludeSvnClassPathEntry(new ZipFileClassPathEntry(file));
+    return new ExcludeSvnClassPathEntry(ZipFileClassPathEntry.get(file));
   }

   protected ClassPathEntry getClassPathEntry2AsMock() {
Index: dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
===================================================================
--- dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java (revision 9867) +++ dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java (working copy)
@@ -193,7 +193,7 @@
       URISyntaxException {
     TreeLogger logger = createTestTreeLogger();
File jarFile = findFile("com/google/gwt/dev/resource/impl/testdata/cpe1.jar");
-    ClassPathEntry cpe1jar = new ZipFileClassPathEntry(jarFile);
+    ClassPathEntry cpe1jar = ZipFileClassPathEntry.get(jarFile);

     // test basic caching
     PathPrefixSet pps1 = new PathPrefixSet();


--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to