/** * Adds target requirements to the graph. The requirements are queued and the call returns; * construction of the graph will happen on a background thread (if additional threads is * non-zero), or when the call to {@link #getDependencyGraph} is made. If it was not possible to * satisfy one or more requirements that must be checked after graph construction is complete. * * <p>The caller must ensure that the same requirement is not passed multiple times to the * builder. Depending on scheduling and memory availability, the cases may be identified and * coalesced (by {@link GraphBuildingContext#resolveRequirement}) into a single logical operation. * Alternatively the resolutions may run to completion to include terminal outputs in the result. * If the function library contains an ambiguity or other aspect that means the resolved value * specification could differ this will result in an invalid dependency graph. * * @param requirements requirements to add, not null and not containing nulls. */ public void addTarget(final Collection<ValueRequirement> requirements) { ArgumentChecker.noNulls(requirements, "requirements"); // Check that the market data availability provider, the function resolver and the calc config // name are non-null checkInjectedInputs(); // Use the context as a build complete lock so that housekeeping thread cannot observe a "built" // state within this atomic block of work synchronized (getContext()) { for (final ValueRequirement requirement : requirements) { addTargetImpl(requirement); } } // If the run-queue was empty, we may not have started enough threads, so double check startBackgroundConstructionJob(); }
/** * Adds a target requirement to the graph. The requirement is queued and the call returns; * construction of the graph will happen on a background thread (if additional threads is * non-zero), or when the call to {@link #getDependencyGraph} is made. If it was not possible to * satisfy the requirement that must be checked after graph construction is complete. * * <p>The caller must ensure that the same requirement is not passed multiple times to the * builder. Depending on scheduling and memory availability, the cases may be identified and * coalesced (by {@link GraphBuildingContext#resolveRequirement}) into a single logical operation. * Alternatively the resolutions may run to completion to include terminal outputs in the result. * If the function library contains an ambiguity or other aspect that means the resolved value * specification could differ this will result in an invalid dependency graph. * * @param requirement requirement to add, not null */ public void addTarget(final ValueRequirement requirement) { ArgumentChecker.notNull(requirement, "requirement"); // Check that the market data availability provider, the function resolver and the calc config // name are non-null checkInjectedInputs(); // Use the context as a build complete lock so that housekeeping thread cannot observe a "built" // state within this atomic block of work synchronized (getContext()) { // Add the value requirement to the graph (actually adds a suitable resolution task to the run // queue) addTargetImpl(requirement); } // If the run-queue was empty, we won't have started a thread, so double check startBackgroundConstructionJob(); }
/** * Add a task to the run queue, increment the count of scheduled steps, and start/wake up a * background thread if the run queue was empty, as this indicates that there are probably no * active threads at this precise moment. * * @param runnable the task to add to the run queue */ protected void addToRunQueue(final ContextRunnable runnable) { // Check if the run queue is empty final boolean dontSpawn = _runQueue.isEmpty(); // Increment the number of scheduled steps _scheduledSteps.incrementAndGet(); // Actually add the task to this DependencyGraphBuilder's run queue _runQueue.add(runnable); // Don't start construction jobs if the queue is empty or a sequential piece of work bounces // between two threads (i.e. there // is already a background thread that is running the caller which can then execute the task it // has just put into the run // queue). The moment the queue is non-empty, start a job if possible. if (!dontSpawn) { startBackgroundConstructionJob(); } }