/** * Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.cache; import java.util.Objects; import com.google.common.collect.ImmutableList; import com.opengamma.util.ArgumentChecker; /** * Key for identifying values cached in a {@link FunctionCache}. * <p> * A key should uniquely identify an object, taking into account the fact that many objects can change * over time or if they are constructed using different data. For example, if a curve were cached the * valuation time should be included in the cache key, as the same curve built for a different valuation * time would not be the same object. * <p> * It is important to remember that the cache is shared across multiple views and multiple calculation * cycles. Therefore the objects in a cache key must create a key that is unique enough to identify * the exact version of an object that might appear in different views or other cycles. * <p> * Every key includes the type of the caller that put the value into the cache. This is to provide a kind of * namespace. It is quite possible for two classes to choose the same values for a cache keys by coincidence, not * necessarily for the same object. This would cause unintended results. Including the type of the object * that inserted the value greatly reduces the chances of this happening. It is assumed the function writer * will be aware of other uses of the cache in the same function, or can easily check. */ public final class CacheKey { /** The type of the object that placed the value in the cache. Provides a type of namespace for cache keys. */ private final Class<?> _functionType; /** The objects that make up the identity of the object stored with the cache key. */ private final ImmutableList<Object> _keys; private CacheKey(Class<?> functionType, ImmutableList<Object> keys) { _functionType = functionType; _keys = keys; } /** * Creates a key for a specified caller type and identifying keys. * * @param callerType the type of the object that inserted the value into the cache * @param key the first of the objects that make up the unique identifier of the cached value * @param keys any other objects that make up the unique identifier of the cached value * @return a cache key whose identity and hash code are derived from the key arguments */ public static CacheKey of(Class<?> callerType, Object key, Object... keys) { ArgumentChecker.notNull(callerType, "callerType"); ArgumentChecker.notNull(key, "key"); ImmutableList<Object> keyList = ImmutableList.builder().add(key).add(keys).build(); return new CacheKey(callerType, keyList); } /** * Creates a key for a specified caller and identifying keys. * * @param caller the object that inserted the value into the cache * @param key the first of the objects that make up the unique identifier of the cached value * @param keys any other objects that make up the unique identifier of the cached value * @return a cache key whose identity and hash code are derived from the key arguments */ public static CacheKey of(Object caller, Object key, Object... keys) { ArgumentChecker.notNull(caller, "caller"); ArgumentChecker.notNull(key, "key"); ImmutableList<Object> keyList = ImmutableList.builder().add(key).add(keys).build(); return new CacheKey(caller.getClass(), keyList); } @Override public int hashCode() { return Objects.hash(_functionType, _keys); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } CacheKey other = (CacheKey) obj; return Objects.equals(this._functionType, other._functionType) && Objects.deepEquals(this._keys, other._keys); } }