diff options
author | Marian Lobur <loburm@google.com> | 2015-06-26 16:03:14 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2015-06-29 16:37:42 +0000 |
commit | be3171e9624ce8ab23a3a9d799d86196f6194f81 (patch) | |
tree | 7a257bcb0384b121ce6ec24328cf712902d35731 /src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternsResultBuilder.java | |
parent | 8a84dd98b8fcdf71494e058e8bc36ed8ae1b6ec8 (diff) |
Refactoring of SkyframeTargetPatternEvaluator. Now instead of making separate calls to skyframeExecutor for each target patterns, all of them are computed in one call.
--
MOS_MIGRATED_REVID=96973513
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternsResultBuilder.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternsResultBuilder.java | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternsResultBuilder.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternsResultBuilder.java new file mode 100644 index 0000000000..22d1356193 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetPatternsResultBuilder.java @@ -0,0 +1,141 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.skyframe; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; +import com.google.devtools.build.lib.cmdline.ResolvedTargets; +import com.google.devtools.build.lib.cmdline.TargetParsingException; +import com.google.devtools.build.lib.packages.NoSuchPackageException; +import com.google.devtools.build.lib.packages.NoSuchTargetException; +import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.packages.PackageIdentifier; +import com.google.devtools.build.lib.packages.Target; +import com.google.devtools.build.lib.syntax.Label; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.WalkableGraph; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * This class encapsulates logic behind computing final target set based on separate results from a + * list of target patterns (eg, //foo:all -//bar/... //foo:test). + */ +abstract class TargetPatternsResultBuilder { + private Map<PackageIdentifier, Package> packages = null; + private boolean hasError = false; + + /** + * Sets that there was an error, during evaluation. + */ + public void setError() { + hasError = true; + } + + /** + * Returns final set of targets and sets error flag if required. + */ + public ResolvedTargets<Target> build(WalkableGraph walkableGraph) throws TargetParsingException { + precomputePackages(walkableGraph); + ResolvedTargets.Builder<Target> resolvedTargetsBuilder = buildInternal(); + if (hasError) { + resolvedTargetsBuilder.setError(); + } + return resolvedTargetsBuilder.build(); + } + + /** + * Transforms {@code ResolvedTargets<Label>} to {@code ResolvedTargets<Target>}. Note that this + * method is using information about packages, so {@link #precomputePackages} has to be called + * before this method. + */ + protected ResolvedTargets.Builder<Target> transformLabelsIntoTargets( + ResolvedTargets<Label> resolvedLabels) { + // precomputePackages has to be called before this method. + ResolvedTargets.Builder<Target> resolvedTargetsBuilder = ResolvedTargets.builder(); + Preconditions.checkNotNull(packages); + for (Label label : resolvedLabels.getTargets()) { + resolvedTargetsBuilder.add(getExistingTarget(label)); + } + for (Label label : resolvedLabels.getFilteredTargets()) { + resolvedTargetsBuilder.remove(getExistingTarget(label)); + } + return resolvedTargetsBuilder; + } + + private void precomputePackages(WalkableGraph walkableGraph) { + Set<PackageIdentifier> packagesToRequest = getPackagesIdentifiers(); + packages = Maps.newHashMapWithExpectedSize(packagesToRequest.size()); + for (PackageIdentifier pkgIdentifier : packagesToRequest) { + packages.put(pkgIdentifier, findPackageInGraph(pkgIdentifier, walkableGraph)); + } + } + + private Target getExistingTarget(Label label) { + Package pkg = Preconditions.checkNotNull(packages.get(label.getPackageIdentifier()), label); + try { + return pkg.getTarget(label.getName()); + } catch (NoSuchTargetException e) { + // This exception should not raise, because we are processing it during TargetPatternValues + // evaluation in SkyframeTargetPatternEvaluator#parseTargetPatternKeys and values with errors + // are not added to final result. + throw new IllegalStateException(e); + } + } + + private Set<PackageIdentifier> getPackagesIdentifiers() { + Set<PackageIdentifier> packagesIdentifiers = new HashSet<>(); + for (Label label : getLabels()) { + packagesIdentifiers.add(label.getPackageIdentifier()); + } + return packagesIdentifiers; + } + + private Package findPackageInGraph(PackageIdentifier pkgIdentifier, + WalkableGraph walkableGraph) { + SkyKey key = PackageValue.key(pkgIdentifier); + Package pkg = null; + NoSuchPackageException nspe = (NoSuchPackageException) walkableGraph.getException(key); + if (nspe != null) { + pkg = nspe.getPackage(); + } else { + pkg = ((PackageValue) walkableGraph.getValue(key)).getPackage(); + } + Preconditions.checkNotNull(pkg, pkgIdentifier); + return pkg; + } + + /** + * Adds the result from expansion of positive target pattern (eg, "//foo:all"). + */ + abstract void addLabelsOfNegativePattern(ResolvedTargets<Label> labels); + + /** + * Adds the result from expansion of negative target pattern (eg, "-//foo:all"). + */ + abstract void addLabelsOfPositivePattern(ResolvedTargets<Label> labels); + + /** + * Returns {@code ResolvedTargets.Builder<Target>} with final set of targets. Note that this + * method doesn't set error flag in result. + */ + abstract ResolvedTargets.Builder<Target> buildInternal() throws TargetParsingException; + + /** + * Returns target labels from all individual results. + */ + protected abstract Iterable<Label> getLabels(); +} |