/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.solutions.library.engine; import java.util.concurrent.ExecutorService; import com.codahale.metrics.MetricRegistry; import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import com.opengamma.sesame.cache.NoOpCacheInvalidator; import com.opengamma.sesame.config.FunctionModelConfig; import com.opengamma.sesame.engine.ComponentMap; import com.opengamma.sesame.engine.FunctionService; import com.opengamma.sesame.engine.ViewFactory; import com.opengamma.sesame.function.AvailableImplementationsImpl; import com.opengamma.sesame.function.AvailableOutputs; import com.opengamma.util.ArgumentChecker; /** * Abstract provider which creates a ViewFactory instance. */ @Singleton public class ViewFactoryProvider implements Provider<ViewFactory> { //TODO parameterise this private static final int s_defaultCacheSize = 5000; private final ComponentMap _componentMap; private final ExecutorService _executorService; private final AvailableOutputs _availableOutputs; private final MetricRegistry _metricRegistry; /** * @param componentMap the component map to use * @param executorService the environment's {@link ExecutorService} * @param availableOutputs the available outputs * @param metricRegistry the metric registry for the environment */ @Inject public ViewFactoryProvider(ComponentMap componentMap, ExecutorService executorService, AvailableOutputs availableOutputs, MetricRegistry metricRegistry) { _componentMap = ArgumentChecker.notNull(componentMap, "componentMap"); _executorService = ArgumentChecker.notNull(executorService, "executorService"); _availableOutputs = ArgumentChecker.notNull(availableOutputs, "availableOutputs"); _metricRegistry = ArgumentChecker.notNull(metricRegistry, "metricRegistry"); } @Override public ViewFactory get() { return new ViewFactory(_executorService, _componentMap, _availableOutputs, new AvailableImplementationsImpl(), FunctionModelConfig.EMPTY, FunctionService.DEFAULT_SERVICES, createCacheBuilder(), new NoOpCacheInvalidator(), Optional.fromNullable(_metricRegistry)); } /** * Creates a cache builder used by the view factory when it needs to create a new cache. * <p> * New caches are created are created whenever data in the current cache needs to be discarded. * Caches are shared between multiple views so it isn't safe to clear an existing cache as * it may be in use. So a new, empty cache is created and supplied to each view at the * start of its next calculation cycle. * * @return the cache builder, not null */ private CacheBuilder<Object, Object> createCacheBuilder() { int nProcessors = Runtime.getRuntime().availableProcessors(); // concurrency level controls how many segments are created in the cache. a segment is locked while a value // is being calculated so we want enough segments to make it highly unlikely that two threads will try // to write a value to the same segment at the same time. // N.B. read operations can happen concurrently with writes, so the concurrency level only affects cache writes int concurrencyLevel = nProcessors * 8; return CacheBuilder.newBuilder() .maximumSize(s_defaultCacheSize) .concurrencyLevel(concurrencyLevel); } }