package edu.berkeley.nlp.mapper; import edu.berkeley.nlp.util.functional.FunctionalUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.concurrent.*; /** * User: aria42 * Date: Feb 19, 2009 */ public class AsynchronousMapper { public static <T> void doMapping(Collection<T> elems, List<? extends SimpleMapper<T>> mappers) { if (elems.isEmpty()) return; final BlockingQueue<T> queue = new ArrayBlockingQueue<T>(elems.size(), true, elems); class Worker implements Runnable { SimpleMapper mapper; int numCompleted = 0; public Worker(SimpleMapper mapper) { this.mapper = mapper; } public void run() { while (!queue.isEmpty()) { try { T elem = queue.poll(1000, TimeUnit.MILLISECONDS); if (elem == null) break; mapper.map(elem); numCompleted++; } catch (InterruptedException e) { e.printStackTrace(); } } } } ExecutorService es = Executors.newFixedThreadPool(mappers.size()); List<Worker> workers = new ArrayList<Worker>(); for (SimpleMapper<T> mapper : mappers) { Worker worker = new Worker(mapper); workers.add(worker); es.execute(worker); } es.shutdown(); try { es.awaitTermination(100000, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } int totalCompleted = 0; for (Worker worker : workers) { totalCompleted += worker.numCompleted; } if (totalCompleted < elems.size()) { throw new RuntimeException("Completed only " + totalCompleted + " out of " + elems.size() + " tasks!"); } if (!queue.isEmpty()) { throw new RuntimeException(); } } public static <T> void doMapping(Iterator<T> it, int batchSize, List<? extends SimpleMapper<T>> mappers) { while (it.hasNext()) { List<T> items = FunctionalUtils.take(it, batchSize); doMapping(items, mappers); } } }