/*
* 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();
}
}