diff --git a/src/dorkbox/util/collections/LockFreeHashMap.java b/src/dorkbox/util/collections/LockFreeHashMap.java index 4b8abd0..b0eb748 100644 --- a/src/dorkbox/util/collections/LockFreeHashMap.java +++ b/src/dorkbox/util/collections/LockFreeHashMap.java @@ -19,6 +19,7 @@ import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; @@ -162,12 +163,44 @@ class LockFreeHashMap implements Map, Cloneable, Serializable { return hashMap.remove(key); } + @SuppressWarnings("Java8CollectionRemoveIf") + public synchronized + void removeAllValues(final V value) { + for (Iterator> iterator = hashMap.entrySet().iterator(); iterator.hasNext(); ) { + final Map.Entry kvEntry = iterator.next(); + if (kvEntry.getValue().equals(value)) { + iterator.remove(); + } + } + } + @Override public synchronized void putAll(final Map map) { this.hashMap.putAll(map); } + /** + * This uses equals to update values. At first glance, this seems like a waste (since if it's equal, why update it?). This is because + * the ONLY location this is used (in the Database, for updating all DeviceUser in the map), equals compares ONLY the DB ID. In only + * this situation, this makes sense (since anything with the same DB ID, we should replace/update the value) + */ + public synchronized + void updateAllWithValue(final V value) { + for (Map.Entry entry : hashMap.entrySet()) { + if (value.equals(entry.getValue())) { + // get's all device IDs that have this user assigned, and reassign the value + entry.setValue(value); + } + } + } + + public synchronized + void replaceAll(Map hashMap) { + this.hashMap.clear(); + this.hashMap.putAll(hashMap); + } + @Override public synchronized void clear() { @@ -212,4 +245,25 @@ class LockFreeHashMap implements Map, Cloneable, Serializable { return mapREF.get(this) .toString(); } + + @SuppressWarnings("unchecked") + public + Collection keys() { + // use the SWP to get a lock-free get of the value + return mapREF.get(this).keySet(); + } + + @SuppressWarnings("unchecked") + public + Map elements() { + // use the SWP to get a lock-free get of the value + return mapREF.get(this); + } + + @SuppressWarnings("unchecked") + public + HashMap backingMap() { + // use the SWP to get a lock-free get of the value + return mapREF.get(this); + } }