hashing strategy argument made consistent across all maps

This commit is contained in:
Alexey Kudravtsev
2013-07-18 13:35:12 +04:00
parent 106c86ede8
commit eb438b5926
7 changed files with 63 additions and 37 deletions
@@ -74,7 +74,7 @@ public class ResolveCache {
}
private static <K,V> ConcurrentWeakHashMap<K, V> createWeakMap() {
return new ConcurrentWeakHashMap<K,V>(100, 0.75f, Runtime.getRuntime().availableProcessors(), ContainerUtil.<ConcurrentWeakHashMap.Key<K,V>>canonicalStrategy());
return new ConcurrentWeakHashMap<K,V>(100, 0.75f, Runtime.getRuntime().availableProcessors(), ContainerUtil.<K>canonicalStrategy());
}
public void clearCache(boolean isPhysical) {
@@ -118,8 +118,8 @@ abstract class ConcurrentRefHashMap<K,V> extends AbstractMap<K,V> implements Con
myMap = new ConcurrentHashMap<Key<K, V>, V>();
}
public ConcurrentRefHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, TObjectHashingStrategy<Key<K, V>> hashingStrategy) {
myMap = new ConcurrentHashMap<Key<K, V>, V>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
public ConcurrentRefHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
myMap = new ConcurrentHashMap<Key<K, V>, V>(initialCapacity, loadFactor, concurrencyLevel, ConcurrentRefHashMap.<K,V>convertKToKeyK(hashingStrategy));
}
public ConcurrentRefHashMap(Map<? extends K, ? extends V> t) {
@@ -128,7 +128,12 @@ abstract class ConcurrentRefHashMap<K,V> extends AbstractMap<K,V> implements Con
}
public ConcurrentRefHashMap(@NotNull final TObjectHashingStrategy<K> hashingStrategy) {
myMap = new ConcurrentHashMap<Key<K, V>, V>(new TObjectHashingStrategy<Key<K, V>>() {
myMap = new ConcurrentHashMap<Key<K, V>, V>(ConcurrentRefHashMap.<K,V>convertKToKeyK(hashingStrategy));
}
@NotNull
private static <K,V> TObjectHashingStrategy<Key<K, V>> convertKToKeyK(@NotNull final TObjectHashingStrategy<K> hashingStrategy) {
return new TObjectHashingStrategy<Key<K, V>>() {
@Override
public int computeHashCode(final Key<K, V> object) {
return hashingStrategy.computeHashCode(object.get());
@@ -138,7 +143,7 @@ abstract class ConcurrentRefHashMap<K,V> extends AbstractMap<K,V> implements Con
public boolean equals(final Key<K, V> o1, final Key<K, V> o2) {
return hashingStrategy.equals(o1.get(), o2.get());
}
} );
};
}
@@ -16,39 +16,43 @@
package com.intellij.util.containers;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.ReferenceQueue;
import java.util.*;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
private final ConcurrentHashMap<K,MyReference<K, V>> myMap;
private final ConcurrentHashMap<K,MyValueReference<K, V>> myMap;
protected final ReferenceQueue<V> myQueue = new ReferenceQueue<V>();
public ConcurrentRefValueHashMap(final Map<K, V> map) {
public ConcurrentRefValueHashMap(@NotNull Map<K, V> map) {
this();
putAll(map);
}
public ConcurrentRefValueHashMap() {
myMap = new ConcurrentHashMap<K, MyReference<K, V>>();
myMap = new ConcurrentHashMap<K, MyValueReference<K, V>>();
}
public ConcurrentRefValueHashMap(int initialCapacity, float loadFactor, int concurrencyLevel) {
myMap = new ConcurrentHashMap<K, MyReference<K, V>>(initialCapacity, loadFactor, concurrencyLevel);
myMap = new ConcurrentHashMap<K, MyValueReference<K, V>>(initialCapacity, loadFactor, concurrencyLevel);
}
public ConcurrentRefValueHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
myMap = new ConcurrentHashMap<K, MyValueReference<K, V>>(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
}
protected interface MyReference<K, V> {
protected interface MyValueReference<K, V> {
@NotNull
K getKey();
V get();
}
private void processQueue() {
while(true){
MyReference<K, V> ref = (MyReference<K, V>)myQueue.poll();
MyValueReference<K, V> ref = (MyValueReference<K, V>)myQueue.poll();
if (ref == null) break;
myMap.remove(ref.getKey(), ref);
}
@@ -56,7 +60,7 @@ abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
@Override
public V get(@NotNull Object key) {
MyReference<K, V> ref = myMap.get(key);
MyValueReference<K, V> ref = myMap.get(key);
if (ref == null) return null;
return ref.get();
}
@@ -64,18 +68,18 @@ abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
@Override
public V put(@NotNull K key, @NotNull V value) {
processQueue();
MyReference<K, V> oldRef = myMap.put(key, createRef(key, value));
MyValueReference<K, V> oldRef = myMap.put(key, createRef(key, value));
return oldRef != null ? oldRef.get() : null;
}
protected abstract MyReference<K, V> createRef(K key, V value);
protected abstract MyValueReference<K, V> createRef(@NotNull K key, @NotNull V value);
@Override
public V putIfAbsent(@NotNull K key, V value) {
MyReference<K, V> newRef = createRef(key, value);
public V putIfAbsent(@NotNull K key, @NotNull V value) {
MyValueReference<K, V> newRef = createRef(key, value);
while (true) {
processQueue();
MyReference<K, V> oldRef = myMap.putIfAbsent(key, newRef);
MyValueReference<K, V> oldRef = myMap.putIfAbsent(key, newRef);
if (oldRef == null) return null;
final V oldVal = oldRef.get();
if (oldVal == null) {
@@ -88,7 +92,7 @@ abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
}
@Override
public boolean remove(@NotNull final Object key, final Object value) {
public boolean remove(@NotNull final Object key, @NotNull Object value) {
processQueue();
return myMap.remove(key, createRef((K)key, (V)value));
}
@@ -102,19 +106,19 @@ abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
@Override
public V replace(@NotNull final K key, @NotNull final V value) {
processQueue();
MyReference<K, V> ref = myMap.replace(key, createRef(key, value));
MyValueReference<K, V> ref = myMap.replace(key, createRef(key, value));
return ref == null ? null : ref.get();
}
@Override
public V remove(Object key) {
processQueue();
MyReference<K, V> ref = myMap.remove(key);
return ref != null ? ref.get() : null;
MyValueReference<K, V> ref = myMap.remove(key);
return ref == null ? null : ref.get();
}
@Override
public void putAll(Map<? extends K, ? extends V> t) {
public void putAll(@NotNull Map<? extends K, ? extends V> t) {
processQueue();
for (K k : t.keySet()) {
V v = t.get(k);
@@ -150,16 +154,18 @@ abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
throw new RuntimeException("method not implemented");
}
@NotNull
@Override
public Set<K> keySet() {
return myMap.keySet();
}
@NotNull
@Override
public Collection<V> values() {
List<V> result = new ArrayList<V>();
final Collection<MyReference<K, V>> refs = myMap.values();
for (MyReference<K, V> ref : refs) {
final Collection<MyValueReference<K, V>> refs = myMap.values();
for (MyValueReference<K, V> ref : refs) {
final V value = ref.get();
if (value != null) {
result.add(value);
@@ -168,6 +174,7 @@ abstract class ConcurrentRefValueHashMap<K,V> implements ConcurrentMap<K,V> {
return result;
}
@NotNull
@Override
public Set<Entry<K, V>> entrySet() {
final Set<K> keys = keySet();
@@ -79,7 +79,7 @@ public final class ConcurrentSoftHashMap<K,V> extends ConcurrentRefHashMap<K,V>
public ConcurrentSoftHashMap(int initialCapacity,
float loadFactor,
int concurrencyLevel,
TObjectHashingStrategy<Key<K, V>> hashingStrategy) {
@NotNull TObjectHashingStrategy<K> hashingStrategy) {
super(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
}
@@ -17,13 +17,15 @@
package com.intellij.util.containers;
import com.intellij.openapi.util.Comparing;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Map;
public final class ConcurrentSoftValueHashMap<K,V> extends ConcurrentRefValueHashMap<K,V> {
public ConcurrentSoftValueHashMap(Map<K, V> map) {
public ConcurrentSoftValueHashMap(@NotNull Map<K, V> map) {
super(map);
}
@@ -35,13 +37,18 @@ public final class ConcurrentSoftValueHashMap<K,V> extends ConcurrentRefValueHas
super(initialCapacity, loadFactor, concurrencyLevel);
}
private static class MySoftReference<K,T> extends SoftReference<T> implements ConcurrentRefValueHashMap.MyReference<K,T> {
public ConcurrentSoftValueHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
super(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
}
private static class MySoftReference<K,T> extends SoftReference<T> implements MyValueReference<K,T> {
private final K key;
private MySoftReference(K key, T referent, ReferenceQueue<T> q) {
private MySoftReference(@NotNull K key, @NotNull T referent, @NotNull ReferenceQueue<T> q) {
super(referent, q);
this.key = key;
}
@NotNull
@Override
public K getKey() {
return key;
@@ -52,7 +59,7 @@ public final class ConcurrentSoftValueHashMap<K,V> extends ConcurrentRefValueHas
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ConcurrentRefValueHashMap.MyReference that = (ConcurrentRefValueHashMap.MyReference)o;
final MyValueReference that = (MyValueReference)o;
return key.equals(that.getKey()) && Comparing.equal(get(), that.get());
}
@@ -63,7 +70,7 @@ public final class ConcurrentSoftValueHashMap<K,V> extends ConcurrentRefValueHas
}
@Override
protected ConcurrentRefValueHashMap.MyReference<K, V> createRef(K key, V value) {
protected MyValueReference<K, V> createRef(@NotNull K key, @NotNull V value) {
return new MySoftReference<K,V>(key, value, myQueue);
}
}
@@ -82,7 +82,7 @@ public final class ConcurrentWeakHashMap<K,V> extends ConcurrentRefHashMap<K,V>
public ConcurrentWeakHashMap(int initialCapacity,
float loadFactor,
int concurrencyLevel,
TObjectHashingStrategy<Key<K, V>> hashingStrategy) {
@NotNull TObjectHashingStrategy<K> hashingStrategy) {
super(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
}
@@ -17,13 +17,15 @@
package com.intellij.util.containers;
import com.intellij.openapi.util.Comparing;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Map;
public final class ConcurrentWeakValueHashMap<K,V> extends ConcurrentRefValueHashMap<K,V> {
public ConcurrentWeakValueHashMap(Map<K, V> map) {
public ConcurrentWeakValueHashMap(@NotNull Map<K, V> map) {
super(map);
}
@@ -35,13 +37,18 @@ public final class ConcurrentWeakValueHashMap<K,V> extends ConcurrentRefValueHas
super(initialCapacity, loadFactor, concurrencyLevel);
}
private static class MyWeakReference<K,T> extends WeakReference<T> implements MyReference<K,T> {
public ConcurrentWeakValueHashMap(int initialCapacity, float loadFactor, int concurrencyLevel, @NotNull TObjectHashingStrategy<K> hashingStrategy) {
super(initialCapacity, loadFactor, concurrencyLevel, hashingStrategy);
}
private static class MyWeakReference<K,T> extends WeakReference<T> implements MyValueReference<K,T> {
private final K key;
private MyWeakReference(K key, T referent, ReferenceQueue<T> q) {
private MyWeakReference(@NotNull K key, @NotNull T referent, @NotNull ReferenceQueue<T> q) {
super(referent, q);
this.key = key;
}
@NotNull
@Override
public K getKey() {
return key;
@@ -52,7 +59,7 @@ public final class ConcurrentWeakValueHashMap<K,V> extends ConcurrentRefValueHas
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final MyReference that = (MyReference)o;
final MyValueReference that = (MyValueReference)o;
return key.equals(that.getKey()) && Comparing.equal(get(), that.get());
}
@@ -63,7 +70,7 @@ public final class ConcurrentWeakValueHashMap<K,V> extends ConcurrentRefValueHas
}
@Override
protected MyReference<K, V> createRef(K key, V value) {
protected MyValueReference<K, V> createRef(@NotNull K key, @NotNull V value) {
return new MyWeakReference<K,V>(key, value, myQueue);
}
}