blob: dfff25096ba5516eba124bb71e5d6b8769da1867 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Nathan Harmataad810502015-07-29 01:33:49 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.skyframe;
15
Nathan Harmataad810502015-07-29 01:33:49 +000016import com.google.common.collect.ImmutableList;
Mark Schaller6df81792015-12-10 18:47:47 +000017import com.google.devtools.build.lib.util.Preconditions;
Nathan Harmataad810502015-07-29 01:33:49 +000018import com.google.devtools.build.skyframe.SkyFunctionName;
19import com.google.devtools.build.skyframe.SkyKey;
Nathan Harmataad810502015-07-29 01:33:49 +000020
21/**
Janak Ramakrishnandf0531f2015-09-23 17:30:04 +000022 * A value for ensuring that an error for a cycle/chain is reported exactly once. This is achieved
23 * by forcing the same value key for two logically equivalent errors and letting Skyframe do its
Nathan Harmataad810502015-07-29 01:33:49 +000024 * magic.
25 */
Michajlo Matijkiw945a42d2015-10-12 16:24:01 +000026class ChainUniquenessUtils {
27
28 private ChainUniquenessUtils() {}
29
30 /**
31 * Create a SkyKey for {@code functionName} with a canonicalized representation of the cycle
32 * specified by {@code chain} as the argument. {@code chain} must be non-empty.
33 */
34 static SkyKey key(SkyFunctionName functionName, ImmutableList<? extends Object> chain) {
Nathan Harmataad810502015-07-29 01:33:49 +000035 Preconditions.checkState(!chain.isEmpty());
Janak Ramakrishnanf745e992016-03-03 08:08:50 +000036 return SkyKey.create(functionName, canonicalize(chain));
Nathan Harmataad810502015-07-29 01:33:49 +000037 }
38
Janak Ramakrishnandf0531f2015-09-23 17:30:04 +000039 private static ImmutableList<Object> canonicalize(ImmutableList<? extends Object> cycle) {
Nathan Harmataad810502015-07-29 01:33:49 +000040 int minPos = 0;
41 String minString = cycle.get(0).toString();
42 for (int i = 1; i < cycle.size(); i++) {
Michajlo Matijkiw945a42d2015-10-12 16:24:01 +000043 // TOOD(bazel-team): Is the toString representation stable enough?
Nathan Harmataad810502015-07-29 01:33:49 +000044 String candidateString = cycle.get(i).toString();
45 if (candidateString.compareTo(minString) < 0) {
46 minPos = i;
47 minString = candidateString;
48 }
49 }
Janak Ramakrishnandf0531f2015-09-23 17:30:04 +000050 ImmutableList.Builder<Object> builder = ImmutableList.builder();
Nathan Harmataad810502015-07-29 01:33:49 +000051 for (int i = 0; i < cycle.size(); i++) {
52 int pos = (minPos + i) % cycle.size();
53 builder.add(cycle.get(pos));
54 }
55 return builder.build();
56 }
57}
58