package org.jactr.core.concurrent;
/*
* default logging
*/
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class FutureManager<K, C>
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(FutureManager.class);
final private ConcurrentMap<K, ListenableFuture<C>> _map;
final private Runnable _noop = new Runnable() {
public void run()
{
}
};
public FutureManager()
{
_map = new ConcurrentHashMap<K, ListenableFuture<C>>();
}
public boolean hasFuture(K key)
{
return _map.containsKey(key);
}
public Future<C> get(K key)
{
return _map.get(key);
}
/**
* retrieve an existing future for the key, or create a new one for it if
* absent
*
* @param key
* @return
*/
public Future<C> acquireOrGet(K key)
{
ListenableFuture<C> future = newFuture();
ListenableFuture<C> originalFuture = _map.putIfAbsent(key, future);
if (originalFuture != null) return originalFuture;
return future;
}
/**
* release the future by setting the result
*
* @param key
* @param result
* @return
*/
public Future<C> release(K key, C result)
{
ListenableFuture<C> future = _map.remove(key);
if (future != null) future.set(result, null);
return future;
}
/**
* release the future by setting the exception
*
* @param key
* @param exception
* @return
*/
public Future<C> release(K key, Throwable exception)
{
ListenableFuture<C> future = _map.remove(key);
if (future != null) future.set(null, exception);
return future;
}
/**
* override if you want to use an extended version of managed future
*
* @return
*/
protected ListenableFuture<C> newFuture()
{
return new ListenableFuture<C>(_noop);
}
}