Skip to content

Commit

Permalink
Improve compiler caching for zip files.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170943780
  • Loading branch information
tadeegan authored and dimvar committed Oct 4, 2017
1 parent 28550be commit 575437b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 7 deletions.
44 changes: 37 additions & 7 deletions src/com/google/javascript/jscomp/PersistentInputStore.java
Expand Up @@ -15,6 +15,8 @@
*/
package com.google.javascript.jscomp;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -44,6 +46,29 @@ private static class CacheEntry {
CacheEntry(String digest) {
this.digest = digest;
}

private Map<String, CompilerInput> zipEntries = ImmutableMap.of();

CompilerInput getCachedZipEntry(SourceFile zipEntry) {
String originalPath = zipEntry.getOriginalPath();
// Avoid allocating a HashMap instance for arbitrary CompilerInputs.
if (zipEntries.isEmpty()) {
zipEntries = new HashMap<>();
}
if (!zipEntries.containsKey(originalPath)) {
zipEntries.put(originalPath, CompilerInput.makePersistentInput(zipEntry));
}
return zipEntries.get(originalPath);
}

void updateDigest(String newDigest) {
if (!newDigest.equals(digest)) {
this.input = null;
this.digest = newDigest;

zipEntries = ImmutableMap.of();
}
}
}

/**
Expand All @@ -53,11 +78,7 @@ private static class CacheEntry {
public void addInput(String path, String digest) {
if (store.containsKey(path)) {
CacheEntry dep = store.get(path);
if (!dep.digest.equals(digest)) {
// Invalidate cache since digest has changed.
dep.digest = digest;
dep.input = null;
}
dep.updateDigest(digest);
} else {
store.put(path, new CacheEntry(digest));
}
Expand All @@ -70,8 +91,17 @@ public void addInput(String path, String digest) {
* <p>If a matching blaze input cannot be found, just create a new compiler input for scratch.
*/
public CompilerInput getCachedCompilerInput(SourceFile source) {
if (store.containsKey(source.getOriginalPath())) {
CacheEntry cacheEntry = store.get(source.getOriginalPath());
String originalPath = source.getOriginalPath();
// For zip files.
if (originalPath.contains(".js.zip!/")) {
int indexOf = originalPath.indexOf(".js.zip!/");
String zipPath = originalPath.substring(0, indexOf + ".js.zip".length());
Preconditions.checkState(store.containsKey(zipPath));
return store.get(zipPath).getCachedZipEntry(source);
}
// For regular files.
if (store.containsKey(originalPath)) {
CacheEntry cacheEntry = store.get(originalPath);
if (cacheEntry.input == null) {
cacheEntry.input = CompilerInput.makePersistentInput(source);
}
Expand Down
29 changes: 29 additions & 0 deletions test/com/google/javascript/jscomp/PersistentInputStoreTest.java
Expand Up @@ -52,4 +52,33 @@ public void testPopulateDependencyInfoDigestChanged() {
// Stored CompilerInput was revoked from cache.
assertThat(testStore.getCachedCompilerInput(file)).isNotSameAs(input);
}

public void testCacheZipFiles() {
PersistentInputStore store = new PersistentInputStore();
store.addInput("path/to/a/zipfile.js.zip", "aaa");

SourceFile zipEntryA = SourceFile.fromFile("path/to/a/zipfile.js.zip!/relative/a.js");
SourceFile zipEntryB = SourceFile.fromFile("path/to/a/zipfile.js.zip!/relative/b.js");

CompilerInput inputA = store.getCachedCompilerInput(zipEntryA);
CompilerInput inputB = store.getCachedCompilerInput(zipEntryB);

// Returns same compiler input. Reused from last compile.
assertThat(inputA).isSameAs(store.getCachedCompilerInput(zipEntryA));
assertThat(inputB).isSameAs(store.getCachedCompilerInput(zipEntryB));

// New compile. Digest did not change.
store.addInput("path/to/a/zipfile.js.zip", "aaa");

// Returns same compiler input. Reused from last compile.
assertThat(inputA).isSameAs(store.getCachedCompilerInput(zipEntryA));
assertThat(inputB).isSameAs(store.getCachedCompilerInput(zipEntryB));

// New Compile. Digest CHANGES!
store.addInput("path/to/a/zipfile.js.zip", "bbb");

// All inputs from the zip are recomputed.
assertThat(inputA).isNotSameAs(store.getCachedCompilerInput(zipEntryA));
assertThat(inputB).isNotSameAs(store.getCachedCompilerInput(zipEntryB));
}
}

0 comments on commit 575437b

Please sign in to comment.