/* * Copyright 2012-present Facebook, Inc. * * 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.facebook.buck.rules; import com.facebook.buck.log.views.JsonViews; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonView; import com.google.common.base.Objects; import com.google.common.hash.HashCode; import javax.annotation.Nullable; /** * RuleKey encapsulates regimented computation of SHA-1 keys that incorporate all BuildRule state * relevant to idempotency. The RuleKey.Builder API conceptually implements the construction of an * ordered map, and the key/val pairs are digested using an internal serialization that guarantees a * 1:1 mapping for each distinct vector of keys <header,k1,...,kn> in * RuleKey.builder(header).set(k1, v1) ... .set(kn, vn).build(). * * <p>Note carefully that in order to reliably avoid accidental collisions, each RuleKey schema, as * defined by the key vector, must have a distinct header. Otherwise it is possible (if unlikely) * for serialized value data to alias serialized key data, with the result being identical RuleKeys * for differing input. In practical terms this means that each BuildRule implementer should specify * a distinct header, and that for all RuleKeys built with a particular header, the sequence of * set() calls should be identical, even if values are missing. The set() methods specifically * handle null values to accommodate this regime. */ public class RuleKey { private final HashCode hashCode; public RuleKey(HashCode hashCode) { this.hashCode = hashCode; } /** * @param hashString string that conforms to the contract of the return value of {@link * com.google.common.hash.HashCode#toString()}. */ public RuleKey(String hashString) { this(HashCode.fromString(hashString)); } public HashCode getHashCode() { return hashCode; } /** @return the {@code toString()} of the hash code that underlies this RuleKey. */ @Override @JsonProperty("hashCode") @JsonView(JsonViews.MachineReadableLog.class) public String toString() { return getHashCode().toString(); } @Override public boolean equals(@Nullable Object obj) { if (!(obj instanceof RuleKey)) { return false; } RuleKey that = (RuleKey) obj; return Objects.equal(this.getHashCode(), that.getHashCode()); } @Override public int hashCode() { return this.getHashCode().hashCode(); } }