aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfTargetsUnderDirectoryValue.java
blob: 2bc376ece901b0be1847326d7ff377df978e9d6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2015 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.skyframe;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
import com.google.devtools.build.lib.pkgcache.FilteringPolicy;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.Objects;

/**
 * Dummy value that is the result of {@link PrepareDepsOfTargetsUnderDirectoryFunction}.
 *
 * <p>Note that even though the {@link PrepareDepsOfTargetsUnderDirectoryFunction} is evaluated
 * entirely because of its side effects (i.e. loading transitive dependencies of targets), this
 * value interacts safely with change pruning, despite the fact that this value is a singleton. When
 * the targets in a package change, the {@link PackageValue} that
 * {@link PrepareDepsOfTargetsUnderDirectoryFunction} depends on will be invalidated, and the
 * PrepareDeps function for that package's directory will be re-evaluated, loading any new
 * transitive dependencies. Change pruning may prevent the re-evaluation of PrepareDeps for
 * directories above that one, but they don't need to be re-run.
 */
public final class PrepareDepsOfTargetsUnderDirectoryValue implements SkyValue {
  @AutoCodec
  public static final PrepareDepsOfTargetsUnderDirectoryValue INSTANCE =
      new PrepareDepsOfTargetsUnderDirectoryValue();

  private PrepareDepsOfTargetsUnderDirectoryValue() {}

  /** Create a prepare deps of targets under directory request. */
  @ThreadSafe
  public static SkyKey key(RepositoryName repository, RootedPath rootedPath,
      ImmutableSet<PathFragment> excludedPaths) {
    return key(repository, rootedPath, excludedPaths, FilteringPolicies.NO_FILTER);
  }

  /**
   * Create a prepare deps of targets under directory request, specifying a filtering policy for
   * targets.
   */
  @ThreadSafe
  public static PrepareDepsOfTargetsUnderDirectoryKey key(
      RepositoryName repository,
      RootedPath rootedPath,
      ImmutableSet<PathFragment> excludedPaths,
      FilteringPolicy filteringPolicy) {
    return PrepareDepsOfTargetsUnderDirectoryKey.create(
        new RecursivePkgKey(repository, rootedPath, excludedPaths), filteringPolicy);
  }

  /**
   * The argument value for {@link SkyKey}s of {@link PrepareDepsOfTargetsUnderDirectoryFunction}.
   */
  @VisibleForTesting
  @AutoCodec
  public static final class PrepareDepsOfTargetsUnderDirectoryKey implements SkyKey {
    private static final Interner<PrepareDepsOfTargetsUnderDirectoryKey> interners =
        BlazeInterners.newWeakInterner();

    private final RecursivePkgKey recursivePkgKey;
    private final FilteringPolicy filteringPolicy;

    private PrepareDepsOfTargetsUnderDirectoryKey(
        RecursivePkgKey recursivePkgKey, FilteringPolicy filteringPolicy) {
      this.recursivePkgKey = Preconditions.checkNotNull(recursivePkgKey);
      this.filteringPolicy = Preconditions.checkNotNull(filteringPolicy);
    }

    @VisibleForTesting
    @AutoCodec.Instantiator
    static PrepareDepsOfTargetsUnderDirectoryKey create(
        RecursivePkgKey recursivePkgKey, FilteringPolicy filteringPolicy) {
      return interners.intern(
          new PrepareDepsOfTargetsUnderDirectoryKey(recursivePkgKey, filteringPolicy));
    }

    public RecursivePkgKey getRecursivePkgKey() {
      return recursivePkgKey;
    }

    public FilteringPolicy getFilteringPolicy() {
      return filteringPolicy;
    }

    @Override
    public SkyFunctionName functionName() {
      return SkyFunctions.PREPARE_DEPS_OF_TARGETS_UNDER_DIRECTORY;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (!(o instanceof PrepareDepsOfTargetsUnderDirectoryKey)) {
        return false;
      }

      PrepareDepsOfTargetsUnderDirectoryKey that = (PrepareDepsOfTargetsUnderDirectoryKey) o;
      return Objects.equals(recursivePkgKey, that.recursivePkgKey)
          && Objects.equals(filteringPolicy, that.filteringPolicy);
    }

    @Override
    public int hashCode() {
      return Objects.hash(recursivePkgKey, filteringPolicy);
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(PrepareDepsOfTargetsUnderDirectoryKey.class)
              .add("pkg-key", recursivePkgKey)
              .add("filtering policy", filteringPolicy)
              .toString();
    }
  }
}