package java.util.concurrent;
import java.util.*;
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
* Implementation of Map interface based on a hash table. <a
* href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html">[Sun
* docs]</a>
*
* @param <K>
* key type
* @param <V>
* value type
*/
public class BaseConcurrentHashMap<K, V> extends AbstractHashMap<K, V>
implements Cloneable, Serializable, Map<K, V>, ConcurrentMap<K, V> {
/**
* Ensures that RPC will consider type parameter K to be exposed. It will be
* pruned by dead code elimination.
*/
@SuppressWarnings("unused")
private K exposeKey;
/**
* Ensures that RPC will consider type parameter V to be exposed. It will be
* pruned by dead code elimination.
*/
@SuppressWarnings("unused")
private V exposeValue;
public BaseConcurrentHashMap() {
}
public BaseConcurrentHashMap(int ignored) {
super(ignored);
}
public BaseConcurrentHashMap(int ignored, float alsoIgnored) {
super(ignored, alsoIgnored);
}
public BaseConcurrentHashMap(Map<? extends K, ? extends V> toBeCopied) {
super(toBeCopied);
}
@Override
public Object clone() {
return new BaseConcurrentHashMap<K, V>(this);
}
@Override
protected native boolean equals(Object value1, Object value2)
/*-{
return @java.util.Objects::equals(Ljava/lang/Object;Ljava/lang/Object;)(value1, value2);
}-*/;
@Override
protected int getHashCode(Object key) {
// Coerce to int -- our classes all do this, but a user-written class might
// not.
return ~~key.hashCode();
}
/**
* If the specified key is not already associated with a value, associate it
* with the given value. Performs
*
* <pre>
* if (!map.containsKey(key))
* return map.put(key, value);
* else
* return map.get(key);
* </pre>
*/
public V putIfAbsent(K key, V value) {
if (!containsKey(key))
return put(key, value);
else
return get(key);
}
/**
* Removes the entry for a key only if currently mapped to a given value.
* Performs
*
* <pre>
* if (map.containsKey(key) && map.get(key).equals(value)) {
* map.remove(key);
* return true;
* } else
* return false;
* </pre>
*/
public boolean remove(Object key, Object value) {
if (containsKey(key) && get(key).equals(value)) {
remove(key);
return true;
} else
return false;
}
/**
* Replaces the entry for a key only if currently mapped to a given value.
* Performs
*
* <pre>
* if (map.containsKey(key) && map.get(key).equals(oldValue)) {
* map.put(key, newValue);
* return true;
* } else
* return false;
* </pre>
*
* except that the action is performed atomically.
*/
public boolean replace(K key, V oldValue, V newValue) {
if (containsKey(key) && get(key).equals(oldValue)) {
put(key, newValue);
return true;
} else
return false;
}
/**
* Replaces the entry for a key only if currently mapped to some value. This
* performs
*
* <pre>
* if (map.containsKey(key)) {
* return map.put(key, value);
* } else
* return null;
* </pre>
*
* except that the action is performed atomically.
*/
public V replace(K key, V value) {
if (containsKey(key)) {
return put(key, value);
} else
return null;
}
}