com.google.devtools.build.lib.analysis.ArtifactsToOwnerLabels.java Source code

Java tutorial

Introduction

Here is the source code for com.google.devtools.build.lib.analysis.ArtifactsToOwnerLabels.java

Source

// Copyright 2018 The Bazel Authors. 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.analysis;

import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.cmdline.Label;
import java.util.HashSet;
import java.util.Set;

/**
 * Morally a {@link SetMultimap} from artifacts to the labels that own them, which may not be just
 * {@link Artifact#getOwnerLabel} depending on the build. Optimizes for artifacts that are owned by
 * their {@link Artifact#getOwnerLabel} by storing them separately.
 */
public class ArtifactsToOwnerLabels {
    private final SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels;
    private final Set<Artifact> artifactsOwnedOnlyByTheirLabels;

    private ArtifactsToOwnerLabels(SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels,
            Set<Artifact> artifactsOwnedOnlyByTheirLabels) {
        this.artifactToMultipleOrDifferentOwnerLabels = artifactToMultipleOrDifferentOwnerLabels;
        this.artifactsOwnedOnlyByTheirLabels = artifactsOwnedOnlyByTheirLabels;
    }

    public Set<Label> getOwners(Artifact artifact) {
        if (artifactsOwnedOnlyByTheirLabels.contains(artifact)) {
            Preconditions.checkState(!artifactToMultipleOrDifferentOwnerLabels.containsKey(artifact),
                    "Artifact %s incorrectly in multiple categories", artifact);
            Label ownerLabel = artifact.getOwnerLabel();
            if (ownerLabel == null) {
                return ImmutableSet.of();
            }
            return ImmutableSet.of(ownerLabel);
        }
        return Preconditions.checkNotNull(artifactToMultipleOrDifferentOwnerLabels.get(artifact), artifact);
    }

    public Set<Artifact> getArtifacts() {
        return Sets.union(artifactsOwnedOnlyByTheirLabels, artifactToMultipleOrDifferentOwnerLabels.keySet());
    }

    public Builder toBuilder() {
        return new Builder(HashMultimap.create(artifactToMultipleOrDifferentOwnerLabels),
                new HashSet<>(artifactsOwnedOnlyByTheirLabels));
    }

    static class Builder {
        private final SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels;
        private final Set<Artifact> artifactsOwnedOnlyByTheirLabels;

        Builder() {
            this(HashMultimap.create(), new HashSet<>());
        }

        private Builder(SetMultimap<Artifact, Label> artifactToMultipleOrDifferentOwnerLabels,
                Set<Artifact> artifactsOwnedOnlyByTheirLabels) {
            this.artifactToMultipleOrDifferentOwnerLabels = artifactToMultipleOrDifferentOwnerLabels;
            this.artifactsOwnedOnlyByTheirLabels = artifactsOwnedOnlyByTheirLabels;
        }

        public Builder addArtifact(Artifact artifact) {
            if (artifactToMultipleOrDifferentOwnerLabels.containsKey(artifact)) {
                Label ownerLabel = artifact.getOwnerLabel();
                if (ownerLabel != null) {
                    artifactToMultipleOrDifferentOwnerLabels.put(artifact, artifact.getOwnerLabel());
                }
            } else {
                artifactsOwnedOnlyByTheirLabels.add(artifact);
            }
            return this;
        }

        public Builder addArtifact(Artifact artifact, Label label) {
            Preconditions.checkNotNull(label, artifact);
            if (label.equals(artifact.getOwnerLabel())) {
                addArtifact(artifact);
            } else {
                artifactToMultipleOrDifferentOwnerLabels.put(artifact, label);
                if (artifactsOwnedOnlyByTheirLabels.remove(artifact)) {
                    // Redoing this call now that we have a mismatched label will force addition into the
                    // multimap.
                    addArtifact(artifact);
                }
            }
            return this;
        }

        ArtifactsToOwnerLabels build() {
            return new ArtifactsToOwnerLabels(artifactToMultipleOrDifferentOwnerLabels,
                    artifactsOwnedOnlyByTheirLabels);
        }
    }
}