Optimize ReplaceOp#findMergedInto for repos with many changes

Change refs are not of interest for checking whether a commit was
merged. Instead of fetching all refs fetch only the branch refs and
make a separate random lookup for the first ref. This is needed to
catch all cases where the target ref is not a standard branch (e.g.
refs/meta/config, refs/meta/dahsboards/...). Do the lookup for the
target ref first so that we even don't need to fetch the branch refs
if it is a hit.

Change-Id: I93e9f6985198eabe3f7ae9b8a8b6fb734f8a6b5c
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2016-02-17 11:52:20 +01:00
parent a1bfee927e
commit 64310757af

View File

@@ -17,7 +17,6 @@ package com.google.gerrit.server.git;
import static com.google.gerrit.common.FooterConstants.CHANGE_ID;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromFooters;
import static com.google.gerrit.server.mail.MailUtil.getRecipientsFromReviewers;
import static org.eclipse.jgit.lib.RefDatabase.ALL;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
@@ -56,6 +55,7 @@ import com.google.inject.assistedinject.AssistedInject;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.PushCertificate;
@@ -438,16 +438,17 @@ public class ReplaceOp extends BatchUpdate.Op {
private Ref findMergedInto(ChangeContext ctx, String first, RevCommit commit) {
try {
Map<String, Ref> all = ctx.getRepository().getRefDatabase().getRefs(ALL);
Ref firstRef = all.get(first);
if (firstRef != null && isMergedInto(ctx.getRevWalk(), commit, firstRef)) {
RefDatabase refDatabase = ctx.getRepository().getRefDatabase();
Ref firstRef = refDatabase.exactRef(first);
if (firstRef != null
&& isMergedInto(ctx.getRevWalk(), commit, firstRef)) {
return firstRef;
}
for (Ref ref : all.values()) {
if (isBranch(ref)) {
if (isMergedInto(ctx.getRevWalk(), commit, ref)) {
return ref;
}
for (Ref ref : refDatabase.getRefs(Constants.R_HEADS).values()) {
if (isMergedInto(ctx.getRevWalk(), commit, ref)) {
return ref;
}
}
return null;
@@ -461,8 +462,4 @@ public class ReplaceOp extends BatchUpdate.Op {
throws IOException {
return rw.isMergedInto(commit, rw.parseCommit(ref.getObjectId()));
}
private static boolean isBranch(Ref ref) {
return ref.getName().startsWith(Constants.R_HEADS);
}
}