LSSTApplications  18.1.0
LSSTDataManagementBasePackage
Classes | Public Member Functions | List of all members
lsst::utils::Cache< Key, Value, KeyHash, KeyPred > Class Template Reference

Cache of most recently used values. More...

#include <Cache.h>

Public Member Functions

 Cache (std::size_t maxElements=0)
 Ctor. More...
 
 Cache (Cache const &)=default
 
 Cache (Cache &&)=default
 
Cacheoperator= (Cache const &)=default
 
Cacheoperator= (Cache &&)=default
 
 ~Cache ()=default
 Dtor. More...
 
template<typename Generator >
Value operator() (Key const &key, Generator func)
 Lookup or generate a value. More...
 
Value operator[] (Key const &key)
 
void add (Key const &key, Value const &value)
 Add a value to the cache. More...
 
std::size_t size () const
 Return the number of values in the cache. More...
 
std::vector< Key > keys () const
 Return all keys in the cache, most recent first. More...
 
bool contains (Key const &key)
 Does the cache contain the key? More...
 
std::size_t capacity () const
 Return the capacity of the cache. More...
 
void reserve (std::size_t maxElements)
 Change the capacity of the cache. More...
 
void flush ()
 Empty the cache. More...
 

Detailed Description

template<typename Key, typename Value, typename KeyHash, typename KeyPred>
class lsst::utils::Cache< Key, Value, KeyHash, KeyPred >

Cache of most recently used values.

This object stores the most recent maxElements values, where maxElements is set in the constructor. Objects (of type Value) are stored by a key (of type Key; hence the need to provide a KeyHash and KeyPred), and the class presents a dict-like interface. Objects may be added to (add) and retrieved from (operator[]) the cache. For ease of use, an interface (operator()) is also provided that will check the cache for an existing key, and if the key is not present, generate it with a function provided by the user.

Note
Value and Key must be copyable.
This header (Cache.h) should generally only be included in source files, not other header files, because you probably don't want all of the boost::multi_index includes in your header. We suggest you se the CacheFwd.h file in your header instead, and hold the Cache as a std::unique_ptr.
Python bindings (for pybind11) are available in lsst/utils/python/Cache.h.

Definition at line 74 of file Cache.h.

Constructor & Destructor Documentation

◆ Cache() [1/3]

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::Cache ( std::size_t  maxElements = 0)
inline

Ctor.

The maximum number of elements may be zero (default), in which case the cache is permitted to grow without limit.

Exception Safety
Strong exception safety: exceptions will return the system to previous state.

Definition at line 84 of file Cache.h.

84  : _maxElements(maxElements) {
85  _container.template get<Hash>().reserve(maxElements);
86 #ifdef LSST_CACHE_DEBUG
87  _debuggingEnabled = false;
88  _hits = 0;
89  _total = 0;
90  _requests.reserve(maxElements);
91 #endif
92  }
void reserve(std::size_t maxElements)
Change the capacity of the cache.
Definition: Cache.h:190

◆ Cache() [2/3]

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::Cache ( Cache< Key, Value, KeyHash, KeyPred > const &  )
default

◆ Cache() [3/3]

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::Cache ( Cache< Key, Value, KeyHash, KeyPred > &&  )
default

◆ ~Cache()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::~Cache ( )
default

Dtor.

Member Function Documentation

◆ add()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
void lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::add ( Key const &  key,
Value const &  value 
)

Add a value to the cache.

If the key is already in the cache, the existing value will be promoted to the most recently used value.

Exception Safety
Basic exception safety: exceptions will leave the system in a valid but unpredictable state.

Definition at line 300 of file Cache.h.

300  {
301  auto result = _lookup(key);
302  if (!result.second) {
303  _addNew(key, value);
304  }
305 }
py::object result
Definition: schema.cc:418
Key< U > key
Definition: Schema.cc:281

◆ capacity()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
std::size_t lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::capacity ( ) const
inline

Return the capacity of the cache.

Exception Safety
No exceptions can be thrown.

Definition at line 183 of file Cache.h.

183 { return _maxElements; }

◆ contains()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
bool lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::contains ( Key const &  key)
inline

Does the cache contain the key?

If the key is in the cache, it will be promoted to the most recently used value.

Exception Safety
Basic exception safety: exceptions will leave the system in a valid but unpredictable state.

Definition at line 177 of file Cache.h.

177 { return _lookup(key).second; }
Key< U > key
Definition: Schema.cc:281

◆ flush()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
void lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::flush ( )

Empty the cache.

Exception Safety
Basic exception safety: exceptions will leave the system in a valid but unpredictable state.

Definition at line 318 of file Cache.h.

318  {
319  while (size() > 0) {
320  _container.template get<Sequence>().pop_back();
321  }
322 }
std::size_t size() const
Return the number of values in the cache.
Definition: Cache.h:160

◆ keys()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
std::vector< Key > lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::keys ( ) const

Return all keys in the cache, most recent first.

Exception Safety
Strong exception safety: exceptions will return the system to previous state.

Definition at line 308 of file Cache.h.

308  {
310  result.reserve(size());
311  for (auto & keyValue : _container.template get<Sequence>()) {
312  result.push_back(keyValue.first);
313  }
314  return result;
315 }
py::object result
Definition: schema.cc:418
T push_back(T... args)
std::size_t size() const
Return the number of values in the cache.
Definition: Cache.h:160
STL class.
T reserve(T... args)

◆ operator()()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
template<typename Generator >
Value lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::operator() ( Key const &  key,
Generator  func 
)

Lookup or generate a value.

If the key is in the cache, the corresponding value is returned. Otherwise, a value is generated by the provided function which is cached and returned. Thus, the (expensive) Generator function only fires if the corresponding value is not already cached.

The Generator function signature should be:

Value func(Key const& key);

Given the possibility of lambdas, we could have made the required function signature so that it took no arguments. However, it's possible the user has some function that produces a value when given a key, so chose to adopt that signature; any other signature would likely require use of a lambda always.

Exception Safety
Basic exception safety: exceptions will leave the system in a valid but unpredictable state.

Definition at line 276 of file Cache.h.

279  {
280  auto result = _lookup(key);
281  if (result.second) {
282  return result.first->second;
283  }
284  Value value = func(key);
285  _addNew(key, value);
286  return value;
287 }
py::object result
Definition: schema.cc:418
Key< U > key
Definition: Schema.cc:281

◆ operator=() [1/2]

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
Cache& lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::operator= ( Cache< Key, Value, KeyHash, KeyPred > const &  )
default

◆ operator=() [2/2]

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
Cache& lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::operator= ( Cache< Key, Value, KeyHash, KeyPred > &&  )
default

◆ operator[]()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
Value lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::operator[] ( Key const &  key)

Definition at line 290 of file Cache.h.

290  {
291  auto result = _lookup(key);
292  if (result.second) {
293  return result.first->second;
294  }
295  throw LSST_EXCEPT(pex::exceptions::NotFoundError,
296  (boost::format("Unable to find key: %s") % key).str());
297 }
py::object result
Definition: schema.cc:418
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
Key< U > key
Definition: Schema.cc:281

◆ reserve()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
void lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::reserve ( std::size_t  maxElements)
inline

Change the capacity of the cache.

Exception Safety
Basic exception safety: exceptions will leave the system in a valid but unpredictable state.

Definition at line 190 of file Cache.h.

190 { _maxElements = maxElements; _trim(); }

◆ size()

template<typename Key , typename Value , typename KeyHash , typename KeyPred >
std::size_t lsst::utils::Cache< Key, Value, KeyHash, KeyPred >::size ( ) const
inline

Return the number of values in the cache.

Exception Safety
Strong exception safety: exceptions will return the system to previous state.

Definition at line 160 of file Cache.h.

160 { return _container.size(); }

The documentation for this class was generated from the following file: