/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.cache; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.opengamma.engine.value.ComputedValue; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.util.ArgumentChecker; // REVIEW kirk 2013-10-02 -- This was originally going to be named // InMemoryViewComputationCache, as that's the more consistent name for this class // given the nomenclature in other contexts. // However, for consistency its source would have been named InMemoryViewComputationCacheSource, // which would have conflicted with the existing one that is backed by InMemoryBinaryDataStore, // which would have meant one of two things: // 1 - All viewprocessor-spring.xml files would have had to be changed; or // 2 - All viewprocessor-spring.xml files would have different behavior // Neither was particularly appealing, and so it has the nomenclature that it has. /** * A simple implementation of {@link ViewComputationCache} that just holds all entries in * an in-memory Map. As such, it avoids the serialization behavior (and associated performance * penalty) of {@link DefaultViewComputationCache}. Therefore it does not need to be * wrapped in a {@link WriteThroughViewComputationCache} for efficient calculation node * performance. * <p/> * Because there is no ability to overflow to off-heap storage in this implementation, * it should <strong>only</strong> be used in a case where testing has established * that the <em>entire</em> value cache can fit in RAM. Otherwise, an {@code OutOfMemoryException} * will be thrown and the JVM will exit. * <p/> * In addition, this implementation cannot support remote calculation nodes. * <p/> * This class was originally requested in <a href="http://jira.opengamma.com/browse/PLAT-4786">PLAT-4786</a>. */ public class MapBackedInMemoryViewComputationCache extends AbstractViewComputationCache { /** * The initial capacity of the underlying ConcurrentHashMap. * This is set extremely high as in practice cache sizes between 500,000 * and 1,000,000 are not uncommon. */ private static final int INITIAL_CAPACITY = 100000; /** * The load factor for the underlying ConcurrentHashMap. This * is the same (0.75) as the default load factor. */ private static final float LOAD_FACTOR = 0.75f; /** * The concurrency level for the underlying ConcurrentHashMap. * This is double the default. */ private static final int CONCURRENCY_LEVEL = 32; /** * The underlying map for shared values. */ private final ConcurrentMap<ValueSpecification, Object> _sharedValues = new ConcurrentHashMap<ValueSpecification, Object>(INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL); /** * The underlying map for private values. */ private final ConcurrentMap<ValueSpecification, Object> _privateValues = new ConcurrentHashMap<ValueSpecification, Object>(INITIAL_CAPACITY, LOAD_FACTOR, CONCURRENCY_LEVEL); public MapBackedInMemoryViewComputationCache() { } public MapBackedInMemoryViewComputationCache(MapBackedInMemoryViewComputationCache existing) { ArgumentChecker.notNull(existing, "existing to be cloned"); _sharedValues.putAll(existing._sharedValues); _privateValues.putAll(existing._privateValues); } /** * Remove all current elements in the underlying maps. */ public void clear() { _sharedValues.clear(); _privateValues.clear(); } @Override public Object getValue(ValueSpecification specification) { ArgumentChecker.notNull(specification, "specification"); Object result = _sharedValues.get(specification); if (result == null) { result = _privateValues.get(specification); } return result; } @Override public void putSharedValue(ComputedValue value) { ArgumentChecker.notNull(value, "value"); _sharedValues.put(value.getSpecification(), value.getValue()); } @Override public void putPrivateValue(ComputedValue value) { ArgumentChecker.notNull(value, "value"); _privateValues.put(value.getSpecification(), value.getValue()); } @Override public Integer estimateValueSize(ComputedValue value) { return null; } }