summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2010-04-26 15:11:41 -0700
committerShawn O. Pearce <spearce@spearce.org>2010-04-26 17:33:53 -0700
commit374c28057a33c580f40a7c78ad906ee9f4d0587e (patch)
tree24e2b596b803ed5375aa303594c31db8f23a532a /org.eclipse.jgit
parenta0a52897ed3fb66ff8a7e1737bf854042f77f0ce (diff)
downloadjgit-374c28057a33c580f40a7c78ad906ee9f4d0587e.tar.gz
jgit-374c28057a33c580f40a7c78ad906ee9f4d0587e.zip
Don't insert the same pack twice into a pack list
If a concurrent thread picks up a newly created PackFile and adds it to the pack list before the IndexPack thread itself can insert the item onto the front of the list, do nothing and use the item that was picked up by that other concurrent scanning thread. This avoids a potential condition where the same pack exists in memory twice, which causes confusion later during a rescan of the directory because we don't know exactly which PackFile instance should be retained into the new list, and which should be discarded. We can stop searching through the old pack list as soon as the sort function declares that the item to insert should be before the item already in the list. Because the list is always sorted by modification time (in seconds), we should never encounter a case where the pack is positioned at the wrong spot in the list. This early break out still permits an efficient implementation of the common case, inserting a new pack at the head of the list. Change-Id: Ice4459bbd4ee9487078aff5257893883d04f05fb Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java13
1 files changed, 13 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java
index 8f96ef5f06..024bd15b03 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java
@@ -292,7 +292,20 @@ public class ObjectDirectory extends ObjectDatabase {
PackList o, n;
do {
o = packList.get();
+
+ // If the pack in question is already present in the list
+ // (picked up by a concurrent thread that did a scan?) we
+ // do not want to insert it a second time.
+ //
final PackFile[] oldList = o.packs;
+ final String name = pf.getPackFile().getName();
+ for (PackFile p : oldList) {
+ if (PackFile.SORT.compare(pf, p) < 0)
+ break;
+ if (name.equals(p.getPackFile().getName()))
+ return;
+ }
+
final PackFile[] newList = new PackFile[1 + oldList.length];
newList[0] = pf;
System.arraycopy(oldList, 0, newList, 1, oldList.length);