package java.util.concurrent;
import java.util.*;
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
* Very basic emulation for SkipListMap; it's just a TreeMap, to implement
* all of the {@link NavigableMap} functionality.
*
* @param <K> key type
* @param <V> value type
*/
public class ConcurrentSkipListMap <K,V> extends TreeMap<K,V> implements Cloneable, Serializable, 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 ConcurrentSkipListMap() {
super();
}
public ConcurrentSkipListMap(Comparator<? super K> comparator) {
super(comparator);
}
/**
* Constructs a new map containing the same mappings as the given map, sorted
* according to the {@linkplain Comparable natural ordering} of the keys.
*
* @param m the map whose mappings are to be placed in this map
* @throws ClassCastException if the keys in <tt>m</tt> are not
* {@link Comparable}, or are not mutually comparable
* @throws NullPointerException if the specified map or any of its keys or
* values are null
*/
public ConcurrentSkipListMap(Map<? extends K,? extends V> m) {
super(m);
}
/**
* Constructs a new map containing the same mappings and using the same
* ordering as the specified sorted map.
*
* @param m the sorted map whose mappings are to be placed in this map, and
* whose comparator is to be used to sort this map
* @throws NullPointerException if the specified sorted map or any of its keys
* or values are null
*/
public ConcurrentSkipListMap(SortedMap<K,? extends V> m) {
super(m);
}
public Object clone() {
return new ConcurrentSkipListMap<K,V>(this);
}
/**
* 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;
}
}