Use changeRefsById to track existing revisions

Most processing paths build up the same sets of ObjectIds, by scanning
through all refs/changes/ and copying them into a temporary set.

Reuse an existing map that is cached after first use and also supports
the autoCloseChanges code path.

It is unlikely that both refs/for/* and refs/heads/* are pushed at the
same time and need to use the map, so there may not be very much reuse
of the data structure within a single execution of ReceiveCommits.

This commit mostly shrinks the code a bit smaller by removing a very
simple redundant processing path.

Change-Id: If2ffd544c821d184593d729fe4ebef77de1860ee
This commit is contained in:
Shawn Pearce
2014-10-17 14:59:00 -07:00
parent e154dbd9f6
commit 2ffd2cb83f

View File

@@ -1467,7 +1467,6 @@ public class ReceiveCommits {
walk.sort(RevSort.TOPO);
walk.sort(RevSort.REVERSE, true);
try {
Set<ObjectId> existing = Sets.newHashSet();
walk.markStart(walk.parseCommit(magicBranch.cmd.getNewId()));
if (magicBranch.baseCommit != null) {
for (RevCommit c : magicBranch.baseCommit) {
@@ -1480,10 +1479,10 @@ public class ReceiveCommits {
} else {
markHeadsAsUninteresting(
walk,
existing,
magicBranch.ctl != null ? magicBranch.ctl.getRefName() : null);
}
Set<ObjectId> existing = changeRefsById().keySet();
List<ChangeLookup> pending = Lists.newArrayList();
final Set<Change.Key> newChangeIds = new HashSet<>();
final int maxBatchChanges =
@@ -1602,23 +1601,15 @@ public class ReceiveCommits {
}
}
private void markHeadsAsUninteresting(
final RevWalk walk,
Set<ObjectId> existing,
@Nullable String forRef) {
private void markHeadsAsUninteresting(RevWalk rw, @Nullable String forRef) {
for (Ref ref : allRefs.values()) {
if (ref.getObjectId() == null) {
continue;
} else if (ref.getName().startsWith(REFS_CHANGES)) {
existing.add(ref.getObjectId());
} else if (ref.getName().startsWith(R_HEADS)
|| (forRef != null && forRef.equals(ref.getName()))) {
if ((ref.getName().startsWith(R_HEADS) || ref.getName().equals(forRef))
&& ref.getObjectId() != null) {
try {
walk.markUninteresting(walk.parseCommit(ref.getObjectId()));
rw.markUninteresting(rw.parseCommit(ref.getObjectId()));
} catch (IOException e) {
log.warn(String.format("Invalid ref %s in %s",
ref.getName(), project.getName()), e);
continue;
}
}
}
@@ -2287,12 +2278,11 @@ public class ReceiveCommits {
walk.reset();
walk.sort(RevSort.NONE);
try {
Set<ObjectId> existing = Sets.newHashSet();
walk.markStart(walk.parseCommit(cmd.getNewId()));
markHeadsAsUninteresting(walk, existing, cmd.getRefName());
markHeadsAsUninteresting(walk, cmd.getRefName());
RevCommit c;
while ((c = walk.next()) != null) {
Set<ObjectId> existing = changeRefsById().keySet();
for (RevCommit c; (c = walk.next()) != null;) {
if (existing.contains(c)) {
continue;
} else if (!validCommit(ctl, cmd, c)) {