This patch fixes the caching logic so that Gwt no longer re-reads and
re-processes all jars on the classpath on every refresh.
Patch by: amitmanjhi
Review by: jat (desk review)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@4830 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
index f7a0420..96f37c9 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
@@ -20,6 +20,7 @@
import java.io.File;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -52,11 +53,21 @@
TreeLogger.DEBUG, "$0");
}
+ private static class ZipFileSnapshot {
+ private final int prefixSetSize;
+ private final Map<AbstractResource, PathPrefix> cachedAnswers;
+
+ ZipFileSnapshot(int prefixSetSize,
+ Map<AbstractResource, PathPrefix> cachedAnswers) {
+ this.prefixSetSize = prefixSetSize;
+ this.cachedAnswers = cachedAnswers;
+ }
+ }
+
private Set<ZipFileResource> allZipFileResources;
- private Map<AbstractResource, PathPrefix> cachedAnswers;
+ private final Map<PathPrefixSet, ZipFileSnapshot> cachedSnapshots = new HashMap<PathPrefixSet, ZipFileSnapshot>(
+ 2); // currently gwt has just 2 ResourceOracles.
private String cachedLocation;
- private PathPrefixSet lastPrefixSet;
- private int lastPrefixSetSize;
private final ZipFile zipFile;
public ZipFileClassPathEntry(ZipFile zipFile) {
@@ -74,13 +85,13 @@
allZipFileResources = buildIndex(logger);
}
- if (cachedAnswers == null || lastPrefixSet != pathPrefixSet
- || lastPrefixSetSize != pathPrefixSet.getSize()) {
- cachedAnswers = computeApplicableResources(logger, pathPrefixSet);
- lastPrefixSet = pathPrefixSet;
- lastPrefixSetSize = pathPrefixSet.getSize();
+ ZipFileSnapshot snapshot = cachedSnapshots.get(pathPrefixSet);
+ if (snapshot == null || snapshot.prefixSetSize != pathPrefixSet.getSize()) {
+ snapshot = new ZipFileSnapshot(pathPrefixSet.getSize(),
+ computeApplicableResources(logger, pathPrefixSet));
+ cachedSnapshots.put(pathPrefixSet, snapshot);
}
- return cachedAnswers;
+ return snapshot.cachedAnswers;
}
@Override
diff --git a/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java b/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
index 560ed05..788449a 100644
--- a/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
+++ b/dev/core/test/com/google/gwt/dev/resource/impl/ResourceOracleImplTest.java
@@ -15,6 +15,10 @@
*/
package com.google.gwt.dev.resource.impl;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.resource.Resource;
+import com.google.gwt.util.tools.Utility;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -28,10 +32,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.dev.resource.Resource;
-import com.google.gwt.util.tools.Utility;
+import java.util.jar.JarFile;
/**
* Tests {@link ResourceOracleImpl}.
@@ -131,6 +132,37 @@
}
}
+ public void testCachingOfJarResources() throws IOException,
+ URISyntaxException {
+ TreeLogger logger = createTestTreeLogger();
+ ClassPathEntry cpe1jar = new ZipFileClassPathEntry(new JarFile(
+ findJarFile("com/google/gwt/dev/resource/impl/testdata/cpe1.jar")));
+
+ // test basic caching
+ PathPrefixSet pps1 = new PathPrefixSet();
+ pps1.add(new PathPrefix("com/google/gwt", null, false));
+ Map<AbstractResource, PathPrefix> resourceMap1 = cpe1jar.findApplicableResources(
+ logger, pps1);
+ assertSame(resourceMap1, cpe1jar.findApplicableResources(logger, pps1));
+
+ // test that cache is invalidated if PathPrefixSet is modified.
+ pps1.add(new PathPrefix("com/google/gwt/user", null, false));
+ Map<AbstractResource, PathPrefix> resourceMap2 = cpe1jar.findApplicableResources(
+ logger, pps1);
+ assertNotSame(resourceMap1, resourceMap2);
+
+ PathPrefixSet pps2 = new PathPrefixSet();
+ pps2.add(new PathPrefix("org/example/bar", null, false));
+ Map<AbstractResource, PathPrefix> resourceMap3 = cpe1jar.findApplicableResources(
+ logger, pps2);
+ // check that the entry did go in the cache
+ assertSame(resourceMap3, cpe1jar.findApplicableResources(logger, pps2));
+
+ // check that the cache does not thrash
+ assertSame(resourceMap2, cpe1jar.findApplicableResources(logger, pps1));
+ assertSame(resourceMap3, cpe1jar.findApplicableResources(logger, pps2));
+ }
+
/**
* Test that ResourceOracleImpl preserves the order in which the same logical
* resource is occurs in multiple ClassPathEntries.