blob: 01fdbfab69a926aaa8775b2d29116de94007597c [file] [log] [blame]
// Copyright (C) 2013 The Android Open Source Project
//
// 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.gerrit.server.query.change;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Converter;
import com.google.common.base.Enums;
import com.google.common.collect.Ordering;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.proto.Protos;
import com.google.gerrit.server.cache.proto.Cache.ConflictKeyProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
@AutoValue
public abstract class ConflictKey {
public static ConflictKey create(
AnyObjectId commit, AnyObjectId otherCommit, SubmitType submitType, boolean contentMerge) {
ObjectId commitCopy = commit.copy();
ObjectId otherCommitCopy = otherCommit.copy();
if (submitType == SubmitType.FAST_FORWARD_ONLY) {
// The conflict check for FF-only is non-symmetrical, and we need to treat (X, Y) differently
// from (Y, X). Store the commits in the input order.
return new AutoValue_ConflictKey(commitCopy, otherCommitCopy, submitType, contentMerge);
}
// Otherwise, the check is symmetrical; sort commit/otherCommit before storing, so the actual
// key is independent of the order in which they are passed to this method.
return new AutoValue_ConflictKey(
Ordering.natural().min(commitCopy, otherCommitCopy),
Ordering.natural().max(commitCopy, otherCommitCopy),
submitType,
contentMerge);
}
@VisibleForTesting
static ConflictKey createWithoutNormalization(
AnyObjectId commit, AnyObjectId otherCommit, SubmitType submitType, boolean contentMerge) {
return new AutoValue_ConflictKey(commit.copy(), otherCommit.copy(), submitType, contentMerge);
}
public abstract ObjectId commit();
public abstract ObjectId otherCommit();
public abstract SubmitType submitType();
public abstract boolean contentMerge();
public enum Serializer implements CacheSerializer<ConflictKey> {
INSTANCE;
private static final Converter<String, SubmitType> SUBMIT_TYPE_CONVERTER =
Enums.stringConverter(SubmitType.class);
@Override
public byte[] serialize(ConflictKey object) {
ObjectIdConverter idConverter = ObjectIdConverter.create();
return Protos.toByteArray(
ConflictKeyProto.newBuilder()
.setCommit(idConverter.toByteString(object.commit()))
.setOtherCommit(idConverter.toByteString(object.otherCommit()))
.setSubmitType(SUBMIT_TYPE_CONVERTER.reverse().convert(object.submitType()))
.setContentMerge(object.contentMerge())
.build());
}
@Override
public ConflictKey deserialize(byte[] in) {
ConflictKeyProto proto = Protos.parseUnchecked(ConflictKeyProto.parser(), in);
ObjectIdConverter idConverter = ObjectIdConverter.create();
return create(
idConverter.fromByteString(proto.getCommit()),
idConverter.fromByteString(proto.getOtherCommit()),
SUBMIT_TYPE_CONVERTER.convert(proto.getSubmitType()),
proto.getContentMerge());
}
}
}