/**
*
*/
package org.codemap.internal;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import org.codemap.MapAlgorithm;
import org.codemap.MapInstance;
public class MapCaches {
private static Executor executor = Executors.newCachedThreadPool();
private Map<Class<? extends MapAlgorithm<?>>,RunnableFuture<?>> cache;
private MapInstance map;
public MapCaches(MapInstance map) {
this.cache = new HashMap<Class<? extends MapAlgorithm<?>>, RunnableFuture<?>>();
this.map = map;
}
private <V> RunnableFuture<?> makeIfAbsent(Class<? extends MapAlgorithm<V>> key) {
synchronized (key) {
RunnableFuture<?> future = cache.get(key);
if (future == null) {
Callable<V> callable;
try {
callable = key.newInstance().setMap(map);
} catch (InstantiationException e) {
System.out.println(e);
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
future = new FutureTask<V>(callable);
cache.put(key, future);
executor.execute(future);
}
return future;
}
}
public boolean isDone(Class<? extends MapAlgorithm<?>> key) {
Future<?> future = cache.get(key);
return future != null && future.isDone();
}
public <V> void run(Class<? extends MapAlgorithm<V>> key) {
this.makeIfAbsent(key);
}
@SuppressWarnings("unchecked")
public <V> V get(Class<? extends MapAlgorithm<V>> key) {
try {
return (V) this.makeIfAbsent(key).get();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new RuntimeException(ex);
} catch (ExecutionException ex) {
throw new RuntimeException(ex);
}
}
}