package com.workshare.msnos.soup.threading;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ConcurrentBuildingMap<K, V> implements Map<K,V> {
public static interface Factory<V> {
public V make();
}
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
private final Map<K, V> map;
private final Factory<V> factory;
public ConcurrentBuildingMap(Factory<V> aFactory) {
map = new HashMap<K, V>();
factory = aFactory;
}
@Override
public V put(K key, V value) {
writeLock.lock();
try {
return map.put(key, value);
} finally {
writeLock.unlock();
}
}
@SuppressWarnings("unchecked")
@Override
public V get(Object key) {
readLock.lock();
try {
V v = map.get(key);
if (v == null) {
v = factory.make();
map.put((K) key, v);
}
return v;
} finally {
readLock.unlock();
}
}
@Override
public V remove(Object key) {
writeLock.lock();
try {
return map.remove(key);
} finally {
writeLock.unlock();
}
}
@Override
public void clear() {
writeLock.lock();
try {
map.clear();
} finally {
writeLock.unlock();
}
}
@Override
public Set<java.util.Map.Entry<K, V>> entrySet() {
readLock.lock();
try {
return new HashSet<java.util.Map.Entry<K, V>>(map.entrySet());
} finally {
readLock.unlock();
}
}
@Override
public boolean isEmpty() {
readLock.lock();
try {
return map.isEmpty();
} finally {
readLock.unlock();
}
}
@Override
public Set<K> keySet() {
readLock.lock();
try {
return new HashSet<K>(map.keySet());
} finally {
readLock.unlock();
}
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
writeLock.lock();
try {
map.putAll(m);
} finally {
writeLock.unlock();
}
}
@Override
public int size() {
readLock.lock();
try {
return map.size();
} finally {
readLock.unlock();
}
}
@Override
public Collection<V> values() {
readLock.lock();
try {
return new HashSet<V>(map.values());
} finally {
readLock.unlock();
}
}
@Override
public boolean containsKey(Object key) {
readLock.lock();
try {
return map.containsKey(key);
} finally {
readLock.unlock();
}
}
@Override
public boolean containsValue(Object value) {
readLock.lock();
try {
return map.containsValue(value);
} finally {
readLock.unlock();
}
}
@Override
public String toString() {
readLock.lock();
try {
return map.toString();
} finally {
readLock.unlock();
}
}
@Override
public int hashCode() {
readLock.lock();
try {
return map.hashCode();
} finally {
readLock.unlock();
}
}
}