aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
diff options
context:
space:
mode:
authorGravatar janakr <janakr@google.com>2018-07-16 16:29:51 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-16 16:31:22 -0700
commitd491bf10f42e213292382c98a1dc439537f00f43 (patch)
tree8971194363c12107cc24594b247dc37f417ab14d /src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
parenta40f9e30d084a63207affe86fa89fcf4516bb2ba (diff)
Automated rollback of commit eb587075b0d6ffab1cf9e69ede1b7e547905e547.
*** Reason for rollback *** Depot has been fixed. RELNOTES[INC]: If the same artifact is generated by two distinct but identical actions, and a downstream action has both those actions' outputs in its inputs, the artifact will now appear twice in the downstream action's inputs. If this causes problems in Skylark actions, you can use the uniquify=True argument in Args.add_args. PiperOrigin-RevId: 204827477
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
index 956e6500e4..d6c258f8de 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionValue.java
@@ -19,10 +19,14 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
+import com.google.devtools.build.lib.actions.ActionInputHelper;
import com.google.devtools.build.lib.actions.ActionLookupData;
import com.google.devtools.build.lib.actions.ActionLookupValue;
import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.OwnerlessArtifactWrapper;
+import com.google.devtools.build.lib.actions.ArtifactOwner;
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.FileStateValue;
import com.google.devtools.build.lib.actions.FileValue;
@@ -34,6 +38,8 @@ import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -245,4 +251,75 @@ public class ActionExecutionValue implements SkyValue {
artifactData, treeArtifactData, additionalOutputData, outputSymlinks, discoveredModules);
}
}
+
+ private static <V> ImmutableMap<Artifact, V> transformKeys(
+ ImmutableMap<Artifact, V> data, Map<OwnerlessArtifactWrapper, Artifact> newArtifactMap) {
+ if (data.isEmpty()) {
+ return data;
+ }
+ ImmutableMap.Builder<Artifact, V> result = ImmutableMap.builderWithExpectedSize(data.size());
+ for (Map.Entry<Artifact, V> entry : data.entrySet()) {
+ Artifact artifact = entry.getKey();
+ Artifact transformedArtifact =
+ newArtifactMap.get(new OwnerlessArtifactWrapper(entry.getKey()));
+ if (transformedArtifact == null) {
+ // If this action generated a tree artifact, then the declared outputs of the action will
+ // not include the contents of the directory corresponding to that artifact, but the
+ // contents are present in this ActionExecutionValue as TreeFileArtifacts. We must create
+ // corresponding artifacts in the shared action's ActionExecutionValue. We can do that since
+ // a TreeFileArtifact is uniquely described by its parent, its owner, and its parent-
+ // relative path. Since the child was not a declared output, the child and parent must be
+ // generated by the same action, hence they have the same owner, and the parent was a
+ // declared output, so it is present in the shared action. Then we can create the new
+ // TreeFileArtifact to have the shared action's version of the parent artifact (instead of
+ // the original parent artifact); the same parent-relative path; and the new parent's
+ // ArtifactOwner.
+ Preconditions.checkState(
+ artifact.hasParent(),
+ "Output artifact %s from one shared action not present in another's outputs (%s)",
+ artifact,
+ newArtifactMap);
+ ArtifactOwner childOwner = artifact.getArtifactOwner();
+ Artifact parent = Preconditions.checkNotNull(artifact.getParent(), artifact);
+ ArtifactOwner parentOwner = parent.getArtifactOwner();
+ Preconditions.checkState(
+ parentOwner.equals(childOwner),
+ "A parent tree artifact %s has a different ArtifactOwner (%s) than its child %s (owned "
+ + "by %s), but both artifacts were generated by the same action",
+ parent,
+ parentOwner,
+ artifact,
+ childOwner);
+ Artifact newParent =
+ Preconditions.checkNotNull(
+ newArtifactMap.get(new OwnerlessArtifactWrapper(parent)),
+ "parent %s of %s was not present in shared action's data (%s)",
+ parent,
+ artifact,
+ newArtifactMap);
+ transformedArtifact =
+ ActionInputHelper.treeFileArtifact(
+ (Artifact.SpecialArtifact) newParent, artifact.getParentRelativePath());
+ }
+ result.put(transformedArtifact, entry.getValue());
+ }
+ return result.build();
+ }
+
+ ActionExecutionValue transformForSharedAction(ImmutableSet<Artifact> outputs) {
+ Map<OwnerlessArtifactWrapper, Artifact> newArtifactMap =
+ outputs
+ .stream()
+ .collect(Collectors.toMap(OwnerlessArtifactWrapper::new, Function.identity()));
+ // This is only called for shared actions, so we'll almost certainly have to transform all keys
+ // in all sets.
+ // Discovered modules come from the action's inputs, and so don't need to be transformed.
+ return create(
+ transformKeys(artifactData, newArtifactMap),
+ transformKeys(treeArtifactData, newArtifactMap),
+ transformKeys(additionalOutputData, newArtifactMap),
+ outputSymlinks,
+ discoveredModules,
+ this instanceof CrossServerUnshareableActionExecutionValue);
+ }
}