package com.datascience.scheduler;
import com.datascience.core.nominal.decision.ILabelProbabilityDistributionCostCalculator;
import com.datascience.core.nominal.decision.LabelProbabilityDistributionCostCalculators;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.datascience.serialization.json.JSONUtils.*;
import static com.google.common.base.Preconditions.checkArgument;
public class SchedulerFactory<T> {
protected interface Creator<U> {
U create(JsonObject params);
}
protected interface ISchedulerCreator<T> extends Creator<IScheduler<T>>{}
protected interface IPriorityCalculatorCreator<T> extends Creator<IPriorityCalculator<T>>{}
protected interface ISchedulerForWorkerCreator<T> extends Creator<ISchedulerForWorker>{}
protected Map<String, ISchedulerCreator<T>> SCHEDULER_CREATORS = new HashMap<String, ISchedulerCreator<T>>();
protected Map<String, IPriorityCalculatorCreator<T>> CALCULATORS = new HashMap<String, IPriorityCalculatorCreator<T>>();
protected Map<String, ISchedulerForWorkerCreator<T>> SCHEDULERS_FOR_WORKERS = new HashMap<String, ISchedulerForWorkerCreator<T>>();
final static Map<String, TimeUnit> PAUSE_UNITS = new HashMap<String, TimeUnit>();
{
SCHEDULER_CREATORS.put(Constants.SCHEDULER_NORMAL, getNormalSchedulerCreator());
SCHEDULER_CREATORS.put(Constants.SCHEDULER_CACHED, getCachedSchedulerCreator());
CALCULATORS.put(Constants.PC_ASSIGN_COUNT, getPCAssignsCount());
CALCULATORS.put(Constants.PC_ASSIGN_COUNT2, getPCAssignsCount());
CALCULATORS.put(Constants.PC_BY_COST, getPCCostBased());
CALCULATORS.put(Constants.PC_BY_COST2, getPCCostBased());
SCHEDULERS_FOR_WORKERS.put(Constants.FOR_WORKERS_FIRST_NOT_SEEN, getFirstNotSeen());
SCHEDULERS_FOR_WORKERS.put(Constants.FOR_WORKERS_CM_BASED, getCostMatrixBased());
PAUSE_UNITS.put(t("seconds"), TimeUnit.SECONDS);
PAUSE_UNITS.put(t("minutes"), TimeUnit.MINUTES);
PAUSE_UNITS.put(t("hours"), TimeUnit.HOURS);
};
protected String getID(JsonObject params, String arg){
JsonElement jo = params.get(arg);
checkArgument(jo != null, "Missing parameter: " + arg);
return t(jo.getAsString());
}
protected ISchedulerCreator<T> getNormalSchedulerCreator(){
return new ISchedulerCreator<T>() {
@Override
public IScheduler<T> create(JsonObject params) {
return new Scheduler<T>();
}
};
}
protected ISchedulerCreator<T> getCachedSchedulerCreator(){
return new ISchedulerCreator<T>() {
@Override
public IScheduler<T> create(JsonObject params) {
ensureDefaultNumber(params, Constants.PAUSE_DURATION, 10);
ensureDefaultString(params, Constants.PAUSE_UNIT, "minutes");
CachedScheduler<T> scheduler = new CachedScheduler<T>();
scheduler.setUpCache(
params.get(Constants.PAUSE_DURATION).getAsLong(),
PAUSE_UNITS.get(t(params.get(Constants.PAUSE_UNIT).getAsString()))
);
return scheduler;
}
};
}
protected IPriorityCalculatorCreator<T> getPCAssignsCount(){
return new IPriorityCalculatorCreator<T>() {
@Override
public IPriorityCalculator<T> create(JsonObject params) {
return new AssignCountPriorityCalculator<T>();
}
};
}
protected IPriorityCalculatorCreator<T> getPCCostBased(){
return new IPriorityCalculatorCreator<T>() {
@Override
public IPriorityCalculator<T> create(JsonObject params) {
String costFun = getDefaultString(params, Constants.COST_METHOD, null);
ILabelProbabilityDistributionCostCalculator ilpcc =
LabelProbabilityDistributionCostCalculators.get(costFun);
// XXX This is not safe ...
return (IPriorityCalculator<T>) new CostBasedPriorityCalculator(ilpcc);
}
};
}
protected ISchedulerForWorkerCreator<T> getCostMatrixBased(){
return new ISchedulerForWorkerCreator<T>() {
@Override
public ISchedulerForWorker create(JsonObject params) {
return (ISchedulerForWorker) new SchedulersForWorker.ConfusionMatrixBased();
}
};
}
protected ISchedulerForWorkerCreator<T> getFirstNotSeen(){
return new ISchedulerForWorkerCreator<T>() {
@Override
public ISchedulerForWorker create(JsonObject params) {
return new SchedulersForWorker.FirstNotSeen<T>();
}
};
}
public IScheduler<T> create(JsonObject params) {
String type = getID(params, Constants.SCHEDULER);
checkArgument(SCHEDULER_CREATORS.containsKey(type), "Unknown scheduler type: " + type);
IScheduler<T> scheduler = SCHEDULER_CREATORS.get(type).create(params);
scheduler.setUpQueue(createPriorityCalculator(params));
scheduler.setSchedulerForWorker(createSchedulerForWorker(params));
Logger.getLogger(this.getClass()).debug(String.format("created scheduler: %s %s",
scheduler.getId(), scheduler.getCalculator().getId()));
return scheduler;
}
protected <U> U createWithDefault(JsonObject params, String paramName, String defaultValue, Map<String, ? extends Creator<U>> creators, String name){
ensureDefaultString(params, paramName, defaultValue);
String kind = getID(params, paramName);
Creator<U> creator = creators.get(kind);
checkArgument(creator != null, "Unknown %s: %s", name, kind);
return creator.create(params);
}
public IPriorityCalculator<T> createPriorityCalculator(JsonObject params){
return createWithDefault(params, Constants.PRIORITY_CALCULATOR, Constants.PC_ASSIGN_COUNT,
CALCULATORS, "priority calculator");
}
public ISchedulerForWorker createSchedulerForWorker(JsonObject params){
return createWithDefault(params, Constants.SCHEDULER_FOR_WORKERS, Constants.FOR_WORKERS_FIRST_NOT_SEEN,
SCHEDULERS_FOR_WORKERS, "scheduler for workers");
}
}