From 556ea233d3b105769dd4b8fcb8a72d545cd44aa1 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 12 Jun 2009 16:00:19 -0700 Subject: [PATCH] UploadPack: Only recompute okToGiveUp() if bases changed If we get a commit we don't recognize, but we haven't added any new common bases to the commonBase set since the last time we ran the okToGiveUp() algorithm, then there is no point in running it again, as the result will not change. Instead we cache the result in a Boolean and just return the cached result until another common base can be found and added to the set. This helps to fix a performance problem when the client is 50,000 commits ahead of the server, and keeps sending them in "have" lines, but the server doesn't recognize them. On every "have" line we will not have updated the common base, but we also aren't yet satisfied that it is OK to give up negotiation. Between the changes introduced by the parent commit and this commit, negotiation in this case of 50,000 ahead now completes instantly, instead of taking hours. Signed-off-by: Shawn O. Pearce Signed-off-by: Robin Rosenberg --- .../src/org/spearce/jgit/transport/UploadPack.java | 27 +++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java b/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java index 5127dadc..5c8df62c 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/UploadPack.java @@ -112,6 +112,9 @@ public class UploadPack { /** Objects on both sides, these don't have to be sent. */ private final List commonBase = new ArrayList(); + /** null if {@link #commonBase} should be examined again. */ + private Boolean okToGiveUp; + /** Marked on objects we sent in our advertisement list. */ private final RevFlag ADVERTISED; @@ -396,15 +399,26 @@ public class UploadPack { o.add(PEER_HAS); if (o instanceof RevCommit) ((RevCommit) o).carry(PEER_HAS); - if (!o.has(COMMON)) { - o.add(COMMON); - commonBase.add(o); - } + addCommonBase(o); } return true; } + private void addCommonBase(final RevObject o) { + if (!o.has(COMMON)) { + o.add(COMMON); + commonBase.add(o); + okToGiveUp = null; + } + } + private boolean okToGiveUp() throws PackProtocolException { + if (okToGiveUp == null) + okToGiveUp = Boolean.valueOf(okToGiveUpImp()); + return okToGiveUp.booleanValue(); + } + + private boolean okToGiveUpImp() throws PackProtocolException { if (commonBase.isEmpty()) return false; @@ -429,10 +443,7 @@ public class UploadPack { if (c == null) break; if (c.has(PEER_HAS)) { - if (!c.has(COMMON)) { - c.add(COMMON); - commonBase.add(c); - } + addCommonBase(c); return true; } } -- 2.11.4.GIT