diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2011-01-27 17:20:36 -0800 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2011-01-28 08:17:20 -0800 |
commit | 17dc6bdafd6399a94f2b64357ea48873f6b71b2a (patch) | |
tree | d89881985cf07d28a100851c8fb12bbbe0bf4227 /org.eclipse.jgit | |
parent | 0b2ac1e929292d385855dba26e753d09a9e14255 (diff) | |
download | jgit-17dc6bdafd6399a94f2b64357ea48873f6b71b2a.tar.gz jgit-17dc6bdafd6399a94f2b64357ea48873f6b71b2a.zip |
ObjectIdSubclassMap: Support duplicate additions
The new addIfAbsent() method combines get() with add(), but does
it in a single step so that the common case of get() returning null
for a new object can immediately insert the object into the map.
Change-Id: Ib599ab4de13ad67665ccfccf3ece52ba3222bcba
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/ObjectIdSubclassMap.java | 47 | ||||
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java | 3 |
2 files changed, 45 insertions, 5 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java index 612e00ea25..ad78acdb8e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdSubclassMap.java @@ -114,12 +114,12 @@ public class ObjectIdSubclassMap<V extends ObjectId> implements Iterable<V> { * <p> * An existing mapping for <b>must not</b> be in this map. Callers must * first call {@link #get(AnyObjectId)} to verify there is no current - * mapping prior to adding a new mapping. + * mapping prior to adding a new mapping, or use + * {@link #addIfAbsent(ObjectId)}. * * @param newValue * the object to store. - * @param - * <Q> + * @param <Q> * type of instance to store. */ public <Q extends V> void add(final Q newValue) { @@ -130,6 +130,47 @@ public class ObjectIdSubclassMap<V extends ObjectId> implements Iterable<V> { } /** + * Store an object for future lookup. + * <p> + * Stores {@code newValue}, but only if there is not already an object for + * the same object name. Callers can tell if the value is new by checking + * the return value with reference equality: + * + * <pre> + * V obj = ...; + * boolean wasNew = map.addIfAbsent(obj) == obj; + * </pre> + * + * @param newValue + * the object to store. + * @return {@code newValue} if stored, or the prior value already stored and + * that would have been returned had the caller used + * {@code get(newValue)} first. + * @param <Q> + * type of instance to store. + */ + public <Q extends V> V addIfAbsent(final Q newValue) { + int i = index(newValue); + V obj; + + while ((obj = obj_hash[i]) != null) { + if (AnyObjectId.equals(obj, newValue)) + return obj; + if (++i == obj_hash.length) + i = 0; + } + + if (obj_hash.length - 1 <= size * 2) { + grow(); + insert(newValue); + } else { + obj_hash[i] = newValue; + } + size++; + return newValue; + } + + /** * @return number of objects in map */ public int size() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java index 001ae288a1..d5f2ac53cb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java @@ -228,8 +228,7 @@ class CachedObjectDirectory extends FileObjectDatabase { switch (result) { case INSERTED: case EXISTS_LOOSE: - if (!unpackedObjects.contains(objectId)) - unpackedObjects.add(objectId); + unpackedObjects.addIfAbsent(objectId); break; case EXISTS_PACKED: |