Search in sources :

Example 1 with Delta

use of com.google.devtools.build.skyframe.Differencer.DiffWithDelta.Delta in project bazel by bazelbuild.

the class SkyframeExecutor method getDiff.

protected Differencer.Diff getDiff(TimestampGranularityMonitor tsgm, Iterable<PathFragment> modifiedSourceFiles, final Path pathEntry) throws InterruptedException {
    if (Iterables.isEmpty(modifiedSourceFiles)) {
        return new ImmutableDiff(ImmutableList.<SkyKey>of(), ImmutableMap.<SkyKey, SkyValue>of());
    }
    // TODO(bazel-team): change ModifiedFileSet to work with RootedPaths instead of PathFragments.
    Iterable<SkyKey> dirtyFileStateSkyKeys = Iterables.transform(modifiedSourceFiles, new Function<PathFragment, SkyKey>() {

        @Override
        public SkyKey apply(PathFragment pathFragment) {
            Preconditions.checkState(!pathFragment.isAbsolute(), "found absolute PathFragment: %s", pathFragment);
            return FileStateValue.key(RootedPath.toRootedPath(pathEntry, pathFragment));
        }
    });
    // We only need to invalidate directory values when a file has been created or deleted or
    // changes type, not when it has merely been modified. Unfortunately we do not have that
    // information here, so we compute it ourselves.
    // TODO(bazel-team): Fancy filesystems could provide it with a hypothetically modified
    // DiffAwareness interface.
    LOG.info("About to recompute filesystem nodes corresponding to files that are known to have " + "changed");
    FilesystemValueChecker fsvc = new FilesystemValueChecker(tsgm, null);
    Map<SkyKey, SkyValue> valuesMap = memoizingEvaluator.getValues();
    Differencer.DiffWithDelta diff = fsvc.getNewAndOldValues(valuesMap, dirtyFileStateSkyKeys, new FileDirtinessChecker());
    Set<SkyKey> valuesToInvalidate = new HashSet<>();
    Map<SkyKey, SkyValue> valuesToInject = new HashMap<>();
    for (Map.Entry<SkyKey, Delta> entry : diff.changedKeysWithNewAndOldValues().entrySet()) {
        SkyKey key = entry.getKey();
        Preconditions.checkState(key.functionName().equals(SkyFunctions.FILE_STATE), key);
        RootedPath rootedPath = (RootedPath) key.argument();
        Delta delta = entry.getValue();
        FileStateValue oldValue = (FileStateValue) delta.getOldValue();
        FileStateValue newValue = (FileStateValue) delta.getNewValue();
        if (newValue != null) {
            valuesToInject.put(key, newValue);
        } else {
            valuesToInvalidate.add(key);
        }
        SkyKey dirListingStateKey = parentDirectoryListingStateKey(rootedPath);
        // Invalidate the directory listing for the path's parent directory if the change was
        // relevant (e.g. path turned from a symlink into a directory) OR if we don't have enough
        // information to determine it was irrelevant.
        boolean changedType = false;
        if (newValue == null) {
            changedType = true;
        } else if (oldValue != null) {
            changedType = !oldValue.getType().equals(newValue.getType());
        } else {
            DirectoryListingStateValue oldDirListingStateValue = (DirectoryListingStateValue) valuesMap.get(dirListingStateKey);
            if (oldDirListingStateValue != null) {
                String baseName = rootedPath.getRelativePath().getBaseName();
                Dirent oldDirent = oldDirListingStateValue.getDirents().maybeGetDirent(baseName);
                changedType = (oldDirent == null) || !compatibleFileTypes(oldDirent.getType(), newValue.getType());
            } else {
                changedType = true;
            }
        }
        if (changedType) {
            valuesToInvalidate.add(dirListingStateKey);
        }
    }
    for (SkyKey key : diff.changedKeysWithoutNewValues()) {
        Preconditions.checkState(key.functionName().equals(SkyFunctions.FILE_STATE), key);
        RootedPath rootedPath = (RootedPath) key.argument();
        valuesToInvalidate.add(parentDirectoryListingStateKey(rootedPath));
    }
    return new ImmutableDiff(valuesToInvalidate, valuesToInject);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) ImmutableDiff(com.google.devtools.build.skyframe.ImmutableDiff) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) Differencer(com.google.devtools.build.skyframe.Differencer) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) SkyValue(com.google.devtools.build.skyframe.SkyValue) FileDirtinessChecker(com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker) Delta(com.google.devtools.build.skyframe.Differencer.DiffWithDelta.Delta) Dirent(com.google.devtools.build.lib.vfs.Dirent) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) HashSet(java.util.HashSet)

Aggregations

ImmutableMap (com.google.common.collect.ImmutableMap)1 FileDirtinessChecker (com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker)1 Dirent (com.google.devtools.build.lib.vfs.Dirent)1 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)1 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)1 Differencer (com.google.devtools.build.skyframe.Differencer)1 Delta (com.google.devtools.build.skyframe.Differencer.DiffWithDelta.Delta)1 ImmutableDiff (com.google.devtools.build.skyframe.ImmutableDiff)1 SkyKey (com.google.devtools.build.skyframe.SkyKey)1 SkyValue (com.google.devtools.build.skyframe.SkyValue)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1