Reuse cached list of existing objects during receive
ReceiveCommits may need to walk through all of the already existing commits more than once during a push, if the user pushes multiple branches in a single transaction. Cache the list (and build it on demand) to avoid walking through the ref map again. Instead of walking through the advertised references, walk through all of the references on the repository. This considers other references that may have been hidden from the user by the VisibleRefFilter, but this isn't really harmful here because that was already validated inside of ReceivePack. Using the full set is however more accurate, and is necessary if the advertised set is reduced to a subset of refs. Change-Id: I9eb3a681266cdf46eddbf6e1abb2abb9c7a05556 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -161,6 +161,7 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
private final Map<RevCommit, ReplaceRequest> replaceByCommit =
|
||||
new HashMap<RevCommit, ReplaceRequest>();
|
||||
|
||||
private Collection<ObjectId> existingObjects;
|
||||
private Map<ObjectId, Ref> refsById;
|
||||
|
||||
private String destTopicName;
|
||||
@@ -808,9 +809,9 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
walk.sort(RevSort.REVERSE, true);
|
||||
try {
|
||||
walk.markStart(walk.parseCommit(newChange.getNewId()));
|
||||
for (final Ref r : rp.getAdvertisedRefs().values()) {
|
||||
for (ObjectId id : existingObjects()) {
|
||||
try {
|
||||
walk.markUninteresting(walk.parseCommit(r.getObjectId()));
|
||||
walk.markUninteresting(walk.parseCommit(id));
|
||||
} catch (IOException e) {
|
||||
continue;
|
||||
}
|
||||
@@ -1412,9 +1413,9 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
walk.sort(RevSort.NONE);
|
||||
try {
|
||||
walk.markStart(walk.parseCommit(cmd.getNewId()));
|
||||
for (final Ref r : rp.getAdvertisedRefs().values()) {
|
||||
for (ObjectId id : existingObjects()) {
|
||||
try {
|
||||
walk.markUninteresting(walk.parseCommit(r.getObjectId()));
|
||||
walk.markUninteresting(walk.parseCommit(id));
|
||||
} catch (IOException e) {
|
||||
continue;
|
||||
}
|
||||
@@ -1432,6 +1433,17 @@ public class ReceiveCommits implements PreReceiveHook, PostReceiveHook {
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<ObjectId> existingObjects() {
|
||||
if (existingObjects == null) {
|
||||
Map<String, Ref> refs = repo.getAllRefs();
|
||||
existingObjects = new ArrayList<ObjectId>(refs.size());
|
||||
for (Ref r : refs.values()) {
|
||||
existingObjects.add(r.getObjectId());
|
||||
}
|
||||
}
|
||||
return existingObjects;
|
||||
}
|
||||
|
||||
private boolean validCommit(final RefControl ctl, final ReceiveCommand cmd,
|
||||
final RevCommit c) throws MissingObjectException, IOException {
|
||||
rp.getRevWalk().parseBody(c);
|
||||
|
||||
Reference in New Issue
Block a user