mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
create ConcurrentMultiMap, remove unused map
This commit is contained in:
@@ -18,11 +18,6 @@
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.3.1-android</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.5.0-M2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
|
||||
@@ -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<K, V> {
|
||||
private Map<K, Collection<V>> _MAP;
|
||||
private Map<K, Collection<V>> MAP() {
|
||||
Map<K, Collection<V>> 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<? extends V> iterable) {
|
||||
Collection<V> values = safeGet(key);
|
||||
for (V v : iterable) {
|
||||
if(!values.add(v)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean putAll(Map<? extends K, ? extends V> map) {
|
||||
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
|
||||
if(!safeGet(entry.getKey()).add(entry.getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
MAP().clear();
|
||||
}
|
||||
|
||||
public Collection<V> safeGet(K key) {
|
||||
return MAP().computeIfAbsent(key, value -> new ConcurrentLinkedQueue<>());
|
||||
}
|
||||
|
||||
public Collection<V> get(K key) {
|
||||
return MAP().get(key);
|
||||
}
|
||||
|
||||
public Set<K> keySet() {
|
||||
return MAP().keySet();
|
||||
}
|
||||
|
||||
public Multiset<K> keys() {
|
||||
Multiset<K> multiset = ConcurrentHashMultiset.create();
|
||||
multiset.addAll(MAP().keySet());
|
||||
return multiset;
|
||||
}
|
||||
|
||||
public Collection<V> values() {
|
||||
Queue<V> values = new ConcurrentLinkedQueue<>();
|
||||
for (Map.Entry<K, Collection<V>> 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<V> replaceValues(K key, Iterable<? extends V> values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<V> removeAll(Object key) {
|
||||
if (key == null)
|
||||
return null;
|
||||
return storage.containsKey(key) ? storage.remove(key) : null;
|
||||
}
|
||||
|
||||
public Collection<Map.Entry<K, V>> entries() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<K, Collection<V>> asMap() {
|
||||
return 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<K,V> implements MultiValuedMap<K,V> {
|
||||
|
||||
private Map<K, Collection<V>> 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<V> values = storage.get(key);
|
||||
if(values==null) {
|
||||
return false;
|
||||
}
|
||||
for (V v : values) {
|
||||
if(v.equals(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> get(K k) {
|
||||
return storage.get(k);
|
||||
}
|
||||
|
||||
private Collection<V> 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<? extends V> iterable) {
|
||||
Collection<V> values = safeGet(k);
|
||||
for (V v : iterable) {
|
||||
if(!values.add(v)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putAll(Map<? extends K, ? extends V> map) {
|
||||
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
|
||||
if(!safeGet(entry.getKey()).add(entry.getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putAll(MultiValuedMap<? extends K, ? extends V> multiValuedMap) {
|
||||
MapIterator<? extends K, ? extends V> iterator = multiValuedMap.mapIterator();
|
||||
while(iterator.hasNext()) {
|
||||
if(!safeGet(iterator.getKey()).add(iterator.getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> remove(Object o) {
|
||||
//noinspection SuspiciousMethodCalls
|
||||
return storage.remove(o);
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousMethodCalls")
|
||||
@Override
|
||||
public boolean removeMapping(Object o, Object v) {
|
||||
Collection<V> values = storage.get(o);
|
||||
return values != null && values.remove(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
storage.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Map.Entry<K, V>> entries() {
|
||||
Collection<Map.Entry<K, V>> collection = new LinkedList<>();
|
||||
collectValues((k,v)->{
|
||||
Map.Entry<K,V> mapEntry = new TempMapEntry(k, v);
|
||||
collection.add(mapEntry);
|
||||
});
|
||||
return collection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiSet<K> keys() {
|
||||
MultiSet<K> multiSet = new HashMultiSet<>();
|
||||
multiSet.addAll(storage.keySet());
|
||||
return multiSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return storage.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<V> values() {
|
||||
List<V> values = new LinkedList<>();
|
||||
for (Map.Entry<K, Collection<V>> entry : storage.entrySet()) {
|
||||
for (V v : entry.getValue()) {
|
||||
values.add(v);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<K, Collection<V>> asMap() {
|
||||
return Collections.unmodifiableMap(storage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapIterator<K, V> mapIterator() {
|
||||
HashedMap<K,V> hashedMap = new HashedMap<>();
|
||||
collectValues(hashedMap::put);
|
||||
return hashedMap.mapIterator();
|
||||
}
|
||||
|
||||
private void collectValues(BiConsumer<K,V> consumer) {
|
||||
for (Map.Entry<K, Collection<V>> entry : storage.entrySet()) {
|
||||
for (V v : entry.getValue()) {
|
||||
consumer.accept(entry.getKey(), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class TempMapEntry implements Map.Entry<K,V> {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -53,14 +54,14 @@ import forge.game.staticability.StaticAbilityUnspentMana;
|
||||
*/
|
||||
public class ManaPool extends ManaConversionMatrix implements Iterable<Mana> {
|
||||
private final Player owner;
|
||||
private Multimap<Byte, Mana> _floatingMana;
|
||||
private Multimap<Byte, Mana> floatingMana() {
|
||||
Multimap<Byte, Mana> result = _floatingMana;
|
||||
private ConcurrentMultiMap<Byte, Mana> _floatingMana;
|
||||
private ConcurrentMultiMap<Byte, Mana> floatingMana() {
|
||||
ConcurrentMultiMap<Byte, Mana> result = _floatingMana;
|
||||
if (result == null) {
|
||||
synchronized (this) {
|
||||
result = _floatingMana;
|
||||
if (result == null) {
|
||||
result = Multimaps.synchronizedMultimap(ArrayListMultimap.create());
|
||||
result = new ConcurrentMultiMap<>();
|
||||
_floatingMana = result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user