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(); } } }