protected InMemoryCompiledFunctionRepository compile( final FunctionCompilationContext context, final FunctionRepository functions, final Instant atInstant, final InMemoryCompiledFunctionRepository before, final InMemoryCompiledFunctionRepository after, final ExecutorService executorService) { final InMemoryCompiledFunctionRepository compiled = new InMemoryCompiledFunctionRepository(context); final ExecutorCompletionService<CompiledFunctionDefinition> completionService = new ExecutorCompletionService<CompiledFunctionDefinition>(executorService); int numCompiles = 0; for (final FunctionDefinition function : functions.getAllFunctions()) { if (addFunctionFromCachedRepository(before, after, compiled, function, atInstant)) { continue; } completionService.submit( new Callable<CompiledFunctionDefinition>() { @Override public CompiledFunctionDefinition call() throws Exception { try { s_logger.debug("Compiling {}", function); return function.compile(context, atInstant); } catch (Exception e) { s_logger.error("Compiling {} threw {}", function.getShortName(), e); throw e; } } }); numCompiles++; } for (int i = 0; i < numCompiles; i++) { Future<CompiledFunctionDefinition> future; try { future = completionService.take(); } catch (InterruptedException e1) { Thread.interrupted(); throw new OpenGammaRuntimeException("Interrupted while compiling function definitions."); } try { CompiledFunctionDefinition compiledFunction = future.get(); compiled.addFunction(compiledFunction); } catch (Exception e) { s_logger.debug("Error compiling function definition", e); // Don't propagate the error outwards; it just won't be in the compiled repository } } return compiled; }
@Override public CompiledFunctionRepository compile( final FunctionRepository repository, final FunctionCompilationContext context, final ExecutorService executor, final InstantProvider atInstantProvider) { clearInvalidCache(context.getFunctionInitId()); final Instant atInstant = Instant.of(atInstantProvider); final Pair<FunctionRepository, Instant> key = Pair.of(repository, atInstant); // Try a previous compilation final InMemoryCompiledFunctionRepository previous = getPreviousCompilation(key); if (previous != null) { if (previous.getLatestInvocationTime() == null) { return previous; } else { if (!atInstant.isAfter(previous.getLatestInvocationTime())) { return previous; } } } // Try a future compilation final InMemoryCompiledFunctionRepository next = getNextCompilation(key); if (next != null) { if (next.getEarliestInvocationTime() == null) { return next; } else { if (!atInstant.isBefore(next.getEarliestInvocationTime())) { return next; } } } // Try the exact timestamp InMemoryCompiledFunctionRepository compiled = getCachedCompilation(key); if (compiled != null) { return compiled; } // Create a compilation, salvaging results from previous and next if possible compiled = compile(context, repository, atInstant, previous, next, executor); cacheCompilation(key, compiled); return compiled; }
protected boolean addFunctionFromCachedRepository( final InMemoryCompiledFunctionRepository before, final InMemoryCompiledFunctionRepository after, final InMemoryCompiledFunctionRepository compiled, final FunctionDefinition function, final Instant atInstant) { if (before != null) { final CompiledFunctionDefinition compiledFunction = before.findDefinition(function.getUniqueId()); if (compiledFunction.getLatestInvocationTime() == null) { // previous one always valid compiled.addFunction(compiledFunction); return true; } else { final Instant validUntil = Instant.of(compiledFunction.getLatestInvocationTime()); if (!validUntil.isBefore(atInstant)) { // previous one still valid compiled.addFunction(compiledFunction); return true; } } } if (after != null) { final CompiledFunctionDefinition compiledFunction = after.findDefinition(function.getUniqueId()); if (compiledFunction.getEarliestInvocationTime() == null) { // next one always valid compiled.addFunction(compiledFunction); return true; } else { final Instant validFrom = Instant.of(compiledFunction.getEarliestInvocationTime()); if (!validFrom.isAfter(atInstant)) { // next one already valid compiled.addFunction(compiledFunction); return true; } } } return false; }