package uk.ac.ebi.biosamples.utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ThreadUtils {

	private static Logger log = LoggerFactory.getLogger(ThreadUtils.class);
	
	public static void checkFutures(Map<? extends Object, Future<Void>> futures, int maxSize) throws InterruptedException,ExecutionException {
		while (futures.size() > maxSize) {
			for (Iterator<? extends Object> i = futures.keySet().iterator(); i.hasNext(); ) {
				Object key = i.next();
				futures.get(key).get();
				i.remove();
			}
		}
	}
	
	public static <T> void checkAndRetryFutures(Map<T, Future<Void>> futures, Map<T, Callable<Void>> callables,
			int maxSize, ExecutorService executionService) throws InterruptedException{
		while (futures.size() > maxSize) {
			List<T> toReRun = new ArrayList<>();
			for (Iterator<T> i = futures.keySet().iterator(); i.hasNext(); ) {
				T key = i.next();
				try {
					futures.get(key).get();
				} catch (ExecutionException e) {
					toReRun.add(key);
				}
				i.remove();
			}
			for (T key : toReRun) {
				log.info("Re-executing "+key);
				futures.put(key, executionService.submit(callables.get(key)));
			}
		}
	}
}

@@ -473,16 +473,20 @@
 c static
+ %3CT%3E
  void ch
@@ -517,36 +517,33 @@
  Object, Future%3C
-Void
+T
 %3E%3E futures, int 
@@ -816,32 +816,34 @@
 public static %3CT
+,U
 %3E void checkAndR
@@ -868,20 +868,17 @@
  Future%3C
-Void
+U
 %3E%3E futur
@@ -901,12 +901,9 @@
 ble%3C
-Void
+U
 %3E%3E c

handle futures more generically