/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.exec.plan; import java.io.PrintStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.threeten.bp.Instant; import com.opengamma.engine.exec.stats.GraphExecutorStatisticsGatherer; import com.opengamma.id.UniqueId; import com.opengamma.id.VersionCorrection; import com.opengamma.util.ArgumentChecker; /** * Describes a way of executing a dependency graph - that is, a sequence of jobs that will produce the desired result. * <p> * An execution plan may be executed on an arbitrary node set, but is typically generated in such a way that it will perform best on a given configuration (for example it might have been created with * the intention of being used on {@code X} calculation nodes, each with {@code Y} available execution threads). */ public class GraphExecutionPlan implements Serializable { private static final long serialVersionUID = 1L; private final String _calculationConfiguration; private final long _functionInitializationId; private final Collection<PlannedJob> _leafJobs; private final int _totalJobs; private final double _meanJobSize; private final double _meanJobCycleCost; private final double _meanJobIOCost; /** * Creates a new execution plan. * * @param calculationConfiguration the configuration name, not null - this will be used for constructing job specifications * @param functionInitializationId [PLAT-2241] this will go soon * @param leafJobs the jobs that will execute first, not null and not containing null - these will refer to other jobs that form part of the full plan * @param totalJobs the total number of jobs in the plan * @param meanJobSize the mean job size * @param meanJobCycleCost the mean of each job's CPU cost * @param meanJobIOCost the mean of each job's I/O cost */ public GraphExecutionPlan(final String calculationConfiguration, final long functionInitializationId, final Collection<PlannedJob> leafJobs, final int totalJobs, final double meanJobSize, final double meanJobCycleCost, final double meanJobIOCost) { ArgumentChecker.notNull(calculationConfiguration, "calculationConfiguration"); ArgumentChecker.notNull(leafJobs, "leafJobs"); assert !leafJobs.contains(null); _calculationConfiguration = calculationConfiguration; _functionInitializationId = functionInitializationId; _leafJobs = new ArrayList<PlannedJob>(leafJobs); _totalJobs = totalJobs; _meanJobSize = meanJobSize; _meanJobCycleCost = meanJobCycleCost; _meanJobIOCost = meanJobIOCost; } protected GraphExecutionPlan(final String calculationConfiguration, final GraphExecutionPlan copyFrom) { ArgumentChecker.notNull(calculationConfiguration, "calculationConfiguration"); _calculationConfiguration = calculationConfiguration; _functionInitializationId = copyFrom._functionInitializationId; _leafJobs = copyFrom._leafJobs; _totalJobs = copyFrom._totalJobs; _meanJobSize = copyFrom._meanJobSize; _meanJobCycleCost = copyFrom._meanJobCycleCost; _meanJobIOCost = copyFrom._meanJobIOCost; } /** * Returns a copy with an altered calculation configuration name. * * @param calculationConfiguration the new calculation configuration name * @return this instance if the name matches, otherwise a new instance */ public GraphExecutionPlan withCalculationConfiguration(final String calculationConfiguration) { if (getCalculationConfiguration().equals(calculationConfiguration)) { return this; } return new GraphExecutionPlan(calculationConfiguration, this); } /** * Returns the calculation configuration name. * * @return the configuration name, not null */ public String getCalculationConfiguration() { return _calculationConfiguration; } protected long getFunctionInitializationId() { return _functionInitializationId; } protected Collection<PlannedJob> getLeafJobs() { return _leafJobs; } protected int getTotalJobs() { return _totalJobs; } protected double getMeanJobSize() { return _meanJobSize; } protected double getMeanJobCycleCost() { return _meanJobCycleCost; } protected double getMeanJobIOCost() { return _meanJobIOCost; } /** * Creates an execution state from the plan. The state may be used to deliver executable jobs that can be used to evaluate the graph that this plan represents. * * @param cycleId the view cycle identifier, not null - this will be used to construct job specifications * @param valuationTime the cycle valuation time, not null - this will be used to construct job specifications * @param resolverVersionCorrection the resolution timestamp, not null - this will be embedded in all jobs * @return the executing graph state, not null, with all "leaf" jobs immediately available for execution */ public ExecutingGraph createExecution(final UniqueId cycleId, final Instant valuationTime, final VersionCorrection resolverVersionCorrection) { return new ExecutingGraph(this, cycleId, valuationTime, resolverVersionCorrection); } public void reportStatistics(final GraphExecutorStatisticsGatherer statistics) { statistics.graphProcessed(getCalculationConfiguration(), getTotalJobs(), getMeanJobSize(), getMeanJobCycleCost(), getMeanJobIOCost()); } public void print(final PrintStream out) { out.println(getCalculationConfiguration() + ", " + getTotalJobs() + " job(s)"); final Map<PlannedJob, Integer> jobs = new HashMap<PlannedJob, Integer>(); for (PlannedJob job : getLeafJobs()) { job.print(out, " ", jobs); } } public void print() { print(System.out); } }