From f52b7abe61034f1f2a8d90a38cc2828a365b02df Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Fri, 15 Nov 2024 20:24:20 +0800 Subject: [PATCH] create ConcurrentMultiMap, remove unused map --- forge-core/pom.xml | 5 - .../util/collect/ConcurrentMultiMap.java | 135 ++++++++++++ .../collect/ConcurrentMultiValuedMap.java | 204 ------------------ .../main/java/forge/game/mana/ManaPool.java | 9 +- 4 files changed, 140 insertions(+), 213 deletions(-) create mode 100644 forge-core/src/main/java/forge/util/collect/ConcurrentMultiMap.java delete mode 100644 forge-core/src/main/java/forge/util/collect/ConcurrentMultiValuedMap.java diff --git a/forge-core/pom.xml b/forge-core/pom.xml index 238b8281163..24740c37a5c 100644 --- a/forge-core/pom.xml +++ b/forge-core/pom.xml @@ -18,11 +18,6 @@ guava 33.3.1-android - - org.apache.commons - commons-collections4 - 4.5.0-M2 - org.apache.commons commons-lang3 diff --git a/forge-core/src/main/java/forge/util/collect/ConcurrentMultiMap.java b/forge-core/src/main/java/forge/util/collect/ConcurrentMultiMap.java new file mode 100644 index 00000000000..bae112acebb --- /dev/null +++ b/forge-core/src/main/java/forge/util/collect/ConcurrentMultiMap.java @@ -0,0 +1,135 @@ +package forge.util.collect; + +import com.google.common.collect.ConcurrentHashMultiset; +import com.google.common.collect.Multiset; + +import java.util.Collection; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; + +public class ConcurrentMultiMap { + private Map> _MAP; + private Map> MAP() { + Map> result = _MAP; + if (result == null) { + synchronized (this) { + result = _MAP; + if (result == null) { + result = new ConcurrentHashMap<>(); + _MAP = result; + } + } + } + return _MAP; + } + + public int size() { + return MAP().size(); + } + + + public boolean isEmpty() { + return MAP().isEmpty(); + } + + @SuppressWarnings("SuspiciousMethodCalls") + public boolean containsKey(Object key) { + if (key == null) + return false; + return MAP().containsKey(key); + } + + public boolean put(K key, V value) { + return safeGet(key).add(value); + } + + @SuppressWarnings("SuspiciousMethodCalls") + public boolean remove(Object key, Object value) { + if (key == null || value == null) + return false; + return MAP().get(key).remove(value); + } + + public boolean putAll(K key, Iterable iterable) { + Collection values = safeGet(key); + for (V v : iterable) { + if(!values.add(v)) { + return false; + } + } + return true; + } + + public boolean putAll(Map map) { + for (Map.Entry entry : map.entrySet()) { + if(!safeGet(entry.getKey()).add(entry.getValue())) { + return false; + } + } + return true; + } + + public void clear() { + MAP().clear(); + } + + public Collection safeGet(K key) { + return MAP().computeIfAbsent(key, value -> new ConcurrentLinkedQueue<>()); + } + + public Collection get(K key) { + return MAP().get(key); + } + + public Set keySet() { + return MAP().keySet(); + } + + public Multiset keys() { + Multiset multiset = ConcurrentHashMultiset.create(); + multiset.addAll(MAP().keySet()); + return multiset; + } + + public Collection values() { + Queue values = new ConcurrentLinkedQueue<>(); + for (Map.Entry> entry : MAP().entrySet()) { + values.addAll(entry.getValue()); + } + return values; + } + + /*@SuppressWarnings("SuspiciousMethodCalls") + public boolean containsValue(Object value) { + if (value == null) + return false; + return storage.containsValue(value); + } + + public boolean containsEntry(Object key, Object value) { + if (key == null || value == null) + return false; + return storage.entrySet().contains(Maps.immutableEntry(key, value)); + } + + public Collection replaceValues(K key, Iterable values) { + return null; + } + + public Collection removeAll(Object key) { + if (key == null) + return null; + return storage.containsKey(key) ? storage.remove(key) : null; + } + + public Collection> entries() { + return null; + } + + public Map> asMap() { + return null; + }*/ +} diff --git a/forge-core/src/main/java/forge/util/collect/ConcurrentMultiValuedMap.java b/forge-core/src/main/java/forge/util/collect/ConcurrentMultiValuedMap.java deleted file mode 100644 index cff6992098a..00000000000 --- a/forge-core/src/main/java/forge/util/collect/ConcurrentMultiValuedMap.java +++ /dev/null @@ -1,204 +0,0 @@ -package forge.util.collect; - -import org.apache.commons.collections4.MapIterator; -import org.apache.commons.collections4.MultiSet; -import org.apache.commons.collections4.MultiValuedMap; -import org.apache.commons.collections4.map.HashedMap; -import org.apache.commons.collections4.multiset.HashMultiSet; - -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.function.BiConsumer; - -public class ConcurrentMultiValuedMap implements MultiValuedMap { - - private Map> storage = new ConcurrentHashMap<>(); - - @Override - public int size() { - return storage.size(); - } - - @Override - public boolean isEmpty() { - return storage.isEmpty(); - } - - @Override - public boolean containsKey(Object o) { - //noinspection SuspiciousMethodCalls - return storage.containsKey(o); - } - - @Override - public boolean containsValue(Object o) { - //noinspection SuspiciousMethodCalls - return storage.containsValue(o); - } - - @Override - public boolean containsMapping(Object key, Object value) { - @SuppressWarnings("SuspiciousMethodCalls") - Collection values = storage.get(key); - if(values==null) { - return false; - } - for (V v : values) { - if(v.equals(value)) { - return true; - } - } - return false; - } - - @Override - public Collection get(K k) { - return storage.get(k); - } - - private Collection safeGet(K key) { - return storage.computeIfAbsent(key, value -> new ConcurrentLinkedQueue<>()); - } - - @Override - public boolean put(K k, V v) { - return safeGet(k).add(v); - } - - @Override - public boolean putAll(K k, Iterable iterable) { - Collection values = safeGet(k); - for (V v : iterable) { - if(!values.add(v)) { - return false; - } - } - return true; - } - - @Override - public boolean putAll(Map map) { - for (Map.Entry entry : map.entrySet()) { - if(!safeGet(entry.getKey()).add(entry.getValue())) { - return false; - } - } - return true; - } - - @Override - public boolean putAll(MultiValuedMap multiValuedMap) { - MapIterator iterator = multiValuedMap.mapIterator(); - while(iterator.hasNext()) { - if(!safeGet(iterator.getKey()).add(iterator.getValue())) { - return false; - } - } - return true; - } - - @Override - public Collection remove(Object o) { - //noinspection SuspiciousMethodCalls - return storage.remove(o); - } - - @SuppressWarnings("SuspiciousMethodCalls") - @Override - public boolean removeMapping(Object o, Object v) { - Collection values = storage.get(o); - return values != null && values.remove(v); - } - - @Override - public void clear() { - storage.clear(); - } - - @Override - public Collection> entries() { - Collection> collection = new LinkedList<>(); - collectValues((k,v)->{ - Map.Entry mapEntry = new TempMapEntry(k, v); - collection.add(mapEntry); - }); - return collection; - } - - @Override - public MultiSet keys() { - MultiSet multiSet = new HashMultiSet<>(); - multiSet.addAll(storage.keySet()); - return multiSet; - } - - @Override - public Set keySet() { - return storage.keySet(); - } - - @Override - public Collection values() { - List values = new LinkedList<>(); - for (Map.Entry> entry : storage.entrySet()) { - for (V v : entry.getValue()) { - values.add(v); - } - } - return values; - } - - @Override - public Map> asMap() { - return Collections.unmodifiableMap(storage); - } - - @Override - public MapIterator mapIterator() { - HashedMap hashedMap = new HashedMap<>(); - collectValues(hashedMap::put); - return hashedMap.mapIterator(); - } - - private void collectValues(BiConsumer consumer) { - for (Map.Entry> entry : storage.entrySet()) { - for (V v : entry.getValue()) { - consumer.accept(entry.getKey(), v); - } - } - } - - private final class TempMapEntry implements Map.Entry { - - private V val; - private final K key; - - TempMapEntry(K key, V value) { - this.val = value; - this.key = key; - } - - @Override - public K getKey() { - return key; - } - - @Override - public V getValue() { - return val; - } - - @Override - public V setValue(V value) { - V old = val; - val = value; - return old; - } - } -} diff --git a/forge-game/src/main/java/forge/game/mana/ManaPool.java b/forge-game/src/main/java/forge/game/mana/ManaPool.java index 53e239a6e7a..aa88e107923 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaPool.java +++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java @@ -42,6 +42,7 @@ import forge.game.replacement.ReplacementType; import forge.game.spellability.AbilityManaPart; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbilityUnspentMana; +import forge.util.collect.ConcurrentMultiMap; /** *

@@ -53,14 +54,14 @@ import forge.game.staticability.StaticAbilityUnspentMana; */ public class ManaPool extends ManaConversionMatrix implements Iterable { private final Player owner; - private Multimap _floatingMana; - private Multimap floatingMana() { - Multimap result = _floatingMana; + private ConcurrentMultiMap _floatingMana; + private ConcurrentMultiMap floatingMana() { + ConcurrentMultiMap result = _floatingMana; if (result == null) { synchronized (this) { result = _floatingMana; if (result == null) { - result = Multimaps.synchronizedMultimap(ArrayListMultimap.create()); + result = new ConcurrentMultiMap<>(); _floatingMana = result; } }