/*
Copyright (C) 2009 Diego Darriba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package es.uvigo.darwin.prottest.exe;
import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
import es.uvigo.darwin.prottest.model.Model;
import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
import es.uvigo.darwin.prottest.util.collection.ModelCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import pal.alignment.Alignment;
/**
* Allows the execution of many model optimizations in a thread pool
*
* @author Diego Darriba
* @since 3.0
*/
public class ParallelModelEstimator extends ObservableModelUpdater
implements ModelUpdaterObserver {
/** The runtime **/
private Runtime runtime = Runtime.getRuntime();
/** The size of parallel tasks **/
private int maxNumberOfTasks;
/** The list of model estimators **/
private List<RunEstimator> estimatorList;
/** The pool of threads **/
private ExecutorService threadPool;
/** Collection of callable objects (tasks) **/
private Collection<Callable<Object>> c = new ArrayList<Callable<Object>>();
/**
* Instantiates a new ParallelModelEstimator with no models to optimize.
* The size of the thread pool is equal to the number of available cores in the machine.
*
* @param alignment the common alignment of the models
*/
public ParallelModelEstimator(Alignment alignment) {
this(-1, alignment);
}
/**
* Instantiates a new ParallelModelEstimator with a set of models to optimize
* The size of the thread pool is equal to the number of available cores in the machine.
*
* @param modelCollection the collection of models to optimize in the pool
*/
public ParallelModelEstimator(ModelCollection modelCollection) {
this(-1, modelCollection);
}
/**
* Instantiates a new ParallelModelEstimator with no models to optimize and
* a fixed size of the thread pool
*
* @param availableThreads the size of the thread pool
* @param alignment the common alignment of the models
*/
public ParallelModelEstimator(int availableThreads, Alignment alignment) {
if (availableThreads < 0) {
availableThreads = runtime.availableProcessors();
}
this.maxNumberOfTasks = availableThreads;
this.estimatorList = new ArrayList<RunEstimator>(maxNumberOfTasks);
this.threadPool = Executors.newFixedThreadPool(maxNumberOfTasks);
}
/**
* Instantiates a new ParallelModelEstimator with a set of models to optimize and
* a fixed size of the thread pool
*
* @param availableThreads the size of the thread pool
* @param modelCollection the collection of models to optimize in the pool
*/
public ParallelModelEstimator(int availableThreads, ModelCollection modelCollection) {
if (availableThreads < 0) {
availableThreads = runtime.availableProcessors();
}
this.estimatorList = new ArrayList<RunEstimator>(maxNumberOfTasks);
}
/**
* Executes the model optimization
*
* @param estimator the model estimator to execute
*
* @return if succesfully added the task
*/
public boolean execute(RunEstimator estimator) {
estimator.addObserver(this);
boolean added = estimatorList.add(estimator);
c.add(Executors.callable(estimator));
Collection<Future<Object>> futures = null;
threadPool.execute(estimator);
return added;
}
/* (non-Javadoc)
* @see es.uvigo.darwin.prottest.observer.ModelUpdaterObserver#update(es.uvigo.darwin.prottest.observer.ObservableModelUpdater, es.uvigo.darwin.prottest.model.Model, es.uvigo.darwin.prottest, es.uvigo.darwin.prottest.global.options.ApplicationOptions)
*/
public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
notifyObservers(model, options);
}
/**
* Checks if exist more tasks in the task queue
*
* @return true, if exist more tasks to execute
*/
public boolean hasMoreTasks() {
for (RunEstimator estimator : estimatorList) {
if (!estimator.getModel().isComputed()) {
return true;
}
}
return false;
}
}