aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto Tyley2013-03-01 16:49:58 (EST)
committerRoberto Tyley2013-03-01 16:49:58 (EST)
commitf1dea3e279f4e8ca118e486cecdf7ab967279df3 (patch)
tree9b01861bb0eb74b459c02c06c16b9372205b262f
parent178d55c24d784bc07adbb0d78de8ba1919843e86 (diff)
downloadjgit-f1dea3e279f4e8ca118e486cecdf7ab967279df3.zip
jgit-f1dea3e279f4e8ca118e486cecdf7ab967279df3.tar.gz
jgit-f1dea3e279f4e8ca118e486cecdf7ab967279df3.tar.bz2
Fix RefUpdate performance for existing Refsrefs/changes/92/10792/1
No longer invoke the expensive RefDatabase.isNameConflicting() check on updating existing refs, reducing batch ref update time by ~97%. The RefDirectory implementation of isNameConflicting() is quite slow (it has to do an expensive loose-ref scan) but it's only necessary to perform this check on ref update if the ref is being *created* - if the ref already exists, we can already guarantee that it does not conflict with any other refs. C-Git seems to use a similar condition before making the is_refname_available() check: https://github.com/git/git/blob/v1.8.1.4/refs.c#L1660-L1670 As an example of the effects on performance, here's a simple timing experiment using The BFG to remove one file from the JGit repo: --- $ wget http://repo1.maven.org/maven2/com/madgag/bfg-repo-cleaner/1.0.1/bfg-1.0.1.jar $ git clone --mirror https://git.eclipse.org/r/p/jgit/jgit.git $ java -jar bfg-1.0.1.jar -D make_jgit.sh jgit.git .... Updating references: 100% (5760/5760) ...Ref update completed in 148,949 ms. BFG run is complete! --- The execution time for the run is completely dominated by the batch ref update at the end. Repeating the experiment with BFG v1.0.2 (using JGit patched with this change), the refs update is dramatically reduced: --- Updating references: 100% (5760/5760) ...Ref update completed in 4,327 ms. --- Change-Id: I9057bc4ee22f9cc269b1cc00c493841c71527cd6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java3
1 files changed, 2 insertions, 1 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
index 394af29..fcf38e6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefUpdate.java
@@ -598,7 +598,8 @@ public abstract class RefUpdate {
RevObject newObj;
RevObject oldObj;
- if (getRefDatabase().isNameConflicting(getName()))
+ // don't make expensive conflict check if this is an existing Ref
+ if (oldValue == null && getRefDatabase().isNameConflicting(getName()))
return Result.LOCK_FAILURE;
try {
if (!tryLock(true))