diff options
author | Mark Schaller <mschaller@google.com> | 2015-05-19 20:27:43 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@google.com> | 2015-05-21 09:46:11 +0000 |
commit | f6e32d64fdf3bf2710ed8f32f64d4113064e3200 (patch) | |
tree | 7dc91f1046953c3f4f902dc477c2503904440124 /src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java | |
parent | 111634a5f7b4ba71c84b660a33af8325284b77d8 (diff) |
Teach skyframe about excluded directories, paths
RecursivePkgFunction now expects both a rooted path to load packages
beneath and a set of paths to exclude. This also augments existing
machinery to deliver this set of paths to exclude.
This leads toward more efficient processing of target patterns in
target pattern sequence evaluation.
--
MOS_MIGRATED_REVID=94020331
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java index 11ed3be239..b814319840 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursivePkgFunction.java @@ -13,6 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.skyframe; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; @@ -20,6 +21,7 @@ import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.PackageIdentifier; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.skyframe.RecursivePkgValue.RecursivePkgKey; import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.Dirent.Type; import com.google.devtools.build.lib.vfs.Path; @@ -31,6 +33,7 @@ import com.google.devtools.build.skyframe.SkyValue; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; @@ -47,9 +50,11 @@ public class RecursivePkgFunction implements SkyFunction { @Override public SkyValue compute(SkyKey skyKey, Environment env) { - RootedPath rootedPath = (RootedPath) skyKey.argument(); + RecursivePkgKey recursivePkgKey = (RecursivePkgKey) skyKey.argument(); + RootedPath rootedPath = recursivePkgKey.getRootedPath(); Path root = rootedPath.getRoot(); PathFragment rootRelativePath = rootedPath.getRelativePath(); + Set<PathFragment> excludedPaths = recursivePkgKey.getExcludedPaths(); SkyKey fileKey = FileValue.key(rootedPath); FileValue fileValue = (FileValue) env.getValue(fileKey); @@ -81,14 +86,13 @@ public class RecursivePkgFunction implements SkyFunction { if (pkgLookupValue.getRoot().equals(root)) { try { PackageValue pkgValue = (PackageValue) - env.getValueOrThrow(PackageValue.key(packageId), - NoSuchPackageException.class); + env.getValueOrThrow(PackageValue.key(packageId), NoSuchPackageException.class); if (pkgValue == null) { return null; } packages.add(pkgValue.getPackage().getName()); } catch (NoSuchPackageException e) { - // The package had errors, but don't fail-fast as there might subpackages below the + // The package had errors, but don't fail-fast as there might be subpackages below the // current directory. env.getListener().handle(Event.error( "package contains errors: " + rootRelativePath.getPathString())); @@ -126,8 +130,35 @@ public class RecursivePkgFunction implements SkyFunction { && PathPackageLocator.DEFAULT_TOP_LEVEL_EXCLUDES.contains(basename)) { continue; } + PathFragment subdirectory = rootRelativePath.getRelative(basename); + + // If this subdirectory is one of the excluded paths, don't do package lookups in it. + if (excludedPaths.contains(subdirectory)) { + continue; + } + + // If we have an excluded path that isn't below this subdirectory, we shouldn't pass that + // excluded path to our recursive package lookup of the subdirectory, because the exclusion + // can't possibly match anything beneath the subdirectory. + // + // For example, if we're currently evaluating directory "a", are looking at its subdirectory + // "a/b", and we have an excluded path "a/c/d", there's no need to pass the excluded path + // "a/c/d" to our evaluation of "a/b". + // + // This strategy should help to get more skyframe sharing. Consider the example above. A + // subsequent request of "a/b/...", without any excluded paths, will be a cache hit. + // + // TODO(bazel-team): Replace the excludedPaths set with a trie or a SortedSet for better + // efficiency. + ImmutableSet.Builder<PathFragment> excludedSubdirectoriesBeneathThisSubdirectory = + ImmutableSet.builder(); + for (PathFragment excludedPath : excludedPaths) { + if (excludedPath.startsWith(subdirectory)) { + excludedSubdirectoriesBeneathThisSubdirectory.add(excludedPath); + } + } SkyKey req = RecursivePkgValue.key(RootedPath.toRootedPath(root, - rootRelativePath.getRelative(basename))); + subdirectory), excludedSubdirectoriesBeneathThisSubdirectory.build()); childDeps.add(req); } Map<SkyKey, SkyValue> childValueMap = env.getValues(childDeps); |