Line data Source code
1 : // Copyright (C) 2013 The Android Open Source Project 2 : // 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. 14 : 15 : package com.google.gerrit.server.query.change; 16 : 17 : import com.google.auto.value.AutoValue; 18 : import com.google.common.annotations.VisibleForTesting; 19 : import com.google.common.base.Converter; 20 : import com.google.common.base.Enums; 21 : import com.google.common.collect.Ordering; 22 : import com.google.gerrit.extensions.client.SubmitType; 23 : import com.google.gerrit.proto.Protos; 24 : import com.google.gerrit.server.cache.proto.Cache.ConflictKeyProto; 25 : import com.google.gerrit.server.cache.serialize.CacheSerializer; 26 : import com.google.gerrit.server.cache.serialize.ObjectIdConverter; 27 : import org.eclipse.jgit.lib.AnyObjectId; 28 : import org.eclipse.jgit.lib.ObjectId; 29 : 30 : @AutoValue 31 5 : public abstract class ConflictKey { 32 : public static ConflictKey create( 33 : AnyObjectId commit, AnyObjectId otherCommit, SubmitType submitType, boolean contentMerge) { 34 5 : ObjectId commitCopy = commit.copy(); 35 5 : ObjectId otherCommitCopy = otherCommit.copy(); 36 5 : if (submitType == SubmitType.FAST_FORWARD_ONLY) { 37 : // The conflict check for FF-only is non-symmetrical, and we need to treat (X, Y) differently 38 : // from (Y, X). Store the commits in the input order. 39 1 : return new AutoValue_ConflictKey(commitCopy, otherCommitCopy, submitType, contentMerge); 40 : } 41 : // Otherwise, the check is symmetrical; sort commit/otherCommit before storing, so the actual 42 : // key is independent of the order in which they are passed to this method. 43 5 : return new AutoValue_ConflictKey( 44 5 : Ordering.natural().min(commitCopy, otherCommitCopy), 45 5 : Ordering.natural().max(commitCopy, otherCommitCopy), 46 : submitType, 47 : contentMerge); 48 : } 49 : 50 : @VisibleForTesting 51 : static ConflictKey createWithoutNormalization( 52 : AnyObjectId commit, AnyObjectId otherCommit, SubmitType submitType, boolean contentMerge) { 53 1 : return new AutoValue_ConflictKey(commit.copy(), otherCommit.copy(), submitType, contentMerge); 54 : } 55 : 56 : public abstract ObjectId commit(); 57 : 58 : public abstract ObjectId otherCommit(); 59 : 60 : public abstract SubmitType submitType(); 61 : 62 : public abstract boolean contentMerge(); 63 : 64 153 : public enum Serializer implements CacheSerializer<ConflictKey> { 65 153 : INSTANCE; 66 : 67 153 : private static final Converter<String, SubmitType> SUBMIT_TYPE_CONVERTER = 68 153 : Enums.stringConverter(SubmitType.class); 69 : 70 : @Override 71 : public byte[] serialize(ConflictKey object) { 72 1 : ObjectIdConverter idConverter = ObjectIdConverter.create(); 73 1 : return Protos.toByteArray( 74 1 : ConflictKeyProto.newBuilder() 75 1 : .setCommit(idConverter.toByteString(object.commit())) 76 1 : .setOtherCommit(idConverter.toByteString(object.otherCommit())) 77 1 : .setSubmitType(SUBMIT_TYPE_CONVERTER.reverse().convert(object.submitType())) 78 1 : .setContentMerge(object.contentMerge()) 79 1 : .build()); 80 : } 81 : 82 : @Override 83 : public ConflictKey deserialize(byte[] in) { 84 1 : ConflictKeyProto proto = Protos.parseUnchecked(ConflictKeyProto.parser(), in); 85 1 : ObjectIdConverter idConverter = ObjectIdConverter.create(); 86 1 : return create( 87 1 : idConverter.fromByteString(proto.getCommit()), 88 1 : idConverter.fromByteString(proto.getOtherCommit()), 89 1 : SUBMIT_TYPE_CONVERTER.convert(proto.getSubmitType()), 90 1 : proto.getContentMerge()); 91 : } 92 : } 93 : }