/** * Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.strata.calc.runner; import java.util.List; import java.util.concurrent.ExecutorService; import com.opengamma.strata.basics.ReferenceData; import com.opengamma.strata.calc.CalculationRules; import com.opengamma.strata.calc.CalculationRunner; import com.opengamma.strata.calc.Results; import com.opengamma.strata.data.MarketData; import com.opengamma.strata.data.scenario.ScenarioMarketData; /** * Component that provides the ability to run calculation tasks. * <p> * This interface is the lower-level counterpart to {@link CalculationRunner}. * It provides the ability to calculate results based on {@link CalculationTasks}. * Unless you need to optimize, the {@code CalculationRunner} is a simpler entry point. * <p> * The purpose of the runner is to produce a grid of results, with a row for each target * and a column for each measure. The targets and columns that define the grid of results * are passed in using an instance of {@code CalculationTasks}. * <p> * The {@code CalculationTasks} instance is obtained using a * {@linkplain CalculationTasks#of(CalculationRules, List, List) static factory method}. * It consists of a list of {@code CalculationTask} instances, where each task instance * corresponds to a single cell in the grid of results. When the {@code CalculationTasks} * instance is created for a set of trades and measures some one-off initialization is performed. * Providing access to the instance allows the initialization to occur once, which could * be a performance optimization if many different calculations are performed with the * same set of trades and measures. * <p> * Once obtained, the {@code CalculationTasks} instance may be used to calculate results. * The four "calculate" methods handle the combination of single versus scenario market data, * and synchronous versus asynchronous. * <p> * A calculation runner is typically obtained using the static methods on this interface. * The instance contains an executor thread-pool, thus care should be taken to ensure * the thread-pool is correctly managed. For example, try-with-resources could be used: * <pre> * try (CalculationTaskRunner runner = CalculationTaskRunner.ofMultiThreaded()) { * // use the runner * } * </pre> */ public interface CalculationTaskRunner extends AutoCloseable { /** * Creates a standard multi-threaded calculation task runner capable of performing calculations. * <p> * This factory creates an executor basing the number of threads on the number of available processors. * It is recommended to use try-with-resources to manage the runner: * <pre> * try (CalculationTaskRunner runner = CalculationTaskRunner.ofMultiThreaded()) { * // use the runner * } * </pre> * * @return the calculation task runner */ public static CalculationTaskRunner ofMultiThreaded() { return DefaultCalculationTaskRunner.ofMultiThreaded(); } /** * Creates a calculation task runner capable of performing calculations, specifying the executor. * <p> * It is the callers responsibility to manage the life-cycle of the executor. * * @param executor the executor to use * @return the calculation task runner */ public static CalculationTaskRunner of(ExecutorService executor) { return DefaultCalculationTaskRunner.of(executor); } //------------------------------------------------------------------------- /** * Performs calculations for a single set of market data. * <p> * This returns a grid of results based on the specified tasks and market data. * The grid will contain a row for each target and a column for each measure. * * @param tasks the calculation tasks to invoke * @param marketData the market data to be used in the calculations * @param refData the reference data to be used in the calculations * @return the grid of calculation results, based on the tasks and market data */ public abstract Results calculate( CalculationTasks tasks, MarketData marketData, ReferenceData refData); /** * Performs calculations asynchronously for a single set of market data, * invoking a listener as each calculation completes. * <p> * This method requires the listener to assemble the results, but it can be much more memory efficient when * calculating aggregate results. If the individual results are discarded after they are incorporated into * the aggregate they can be garbage collected. * * @param tasks the calculation tasks to invoke * @param marketData the market data to be used in the calculations * @param refData the reference data to be used in the calculations * @param listener listener that is invoked when individual results are calculated */ public abstract void calculateAsync( CalculationTasks tasks, MarketData marketData, ReferenceData refData, CalculationListener listener); //------------------------------------------------------------------------- /** * Performs calculations for multiple scenarios, each with a different set of market data. * <p> * This returns a grid of results based on the specified tasks and market data. * The grid will contain a row for each target and a column for each measure. * Each cell will contain multiple results, one for each scenario. * * @param tasks the calculation tasks to invoke * @param marketData the market data to be used in the calculations * @param refData the reference data to be used in the calculations * @return the grid of calculation results, based on the tasks and market data */ public abstract Results calculateMultiScenario( CalculationTasks tasks, ScenarioMarketData marketData, ReferenceData refData); /** * Performs calculations asynchronously for a multiple scenarios, each with a different set of market data, * invoking a listener as each calculation completes. * <p> * This method requires the listener to assemble the results, but it can be much more memory efficient when * calculating aggregate results. If the individual results are discarded after they are incorporated into * the aggregate they can be garbage collected. * * @param tasks the calculation tasks to invoke * @param marketData the market data to be used in the calculations * @param refData the reference data to be used in the calculations * @param listener listener that is invoked when individual results are calculated */ public abstract void calculateMultiScenarioAsync( CalculationTasks tasks, ScenarioMarketData marketData, ReferenceData refData, CalculationListener listener); //------------------------------------------------------------------------- /** * Closes any resources held by the component. * <p> * If the component holds an {@link ExecutorService}, this method will typically * call {@link ExecutorService#shutdown()}. */ @Override public abstract void close(); }