From 374c28057a33c580f40a7c78ad906ee9f4d0587e Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 26 Apr 2010 15:11:41 -0700 Subject: [PATCH] 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 --- .../src/org/eclipse/jgit/lib/ObjectDirectory.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 8f96ef5f0..024bd15b0 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 @@ private void insertPack(final PackFile pf) { 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);