Browse Source

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>
stable-0.8
Shawn O. Pearce 15 years ago
parent
commit
374c28057a
  1. 13
      org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java

13
org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java

@ -292,7 +292,20 @@ public class ObjectDirectory extends ObjectDatabase {
PackList o, n; PackList o, n;
do { do {
o = packList.get(); 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 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]; final PackFile[] newList = new PackFile[1 + oldList.length];
newList[0] = pf; newList[0] = pf;
System.arraycopy(oldList, 0, newList, 1, oldList.length); System.arraycopy(oldList, 0, newList, 1, oldList.length);

Loading…
Cancel
Save