22 #ifndef LSST_UTILS_CACHE_H
23 #define LSST_UTILS_CACHE_H
28 #include "boost/multi_index_container.hpp"
29 #include "boost/multi_index/sequenced_index.hpp"
30 #include "boost/multi_index/hashed_index.hpp"
31 #include "boost/multi_index/composite_key.hpp"
32 #include "boost/multi_index/member.hpp"
33 #include "boost/format.hpp"
41 #ifdef LSST_CACHE_DEBUG
73 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
85 _container.template get<Hash>().reserve(maxElements);
86 #ifdef LSST_CACHE_DEBUG
87 _debuggingEnabled =
false;
90 _requests.reserve(maxElements);
101 #ifdef LSST_CACHE_DEBUG
129 template <
typename Generator>
153 void add(Key
const&
key, Value
const& value);
199 #ifdef LSST_CACHE_DEBUG
200 void enableDebugging() { _debuggingEnabled =
true; }
209 _container.template get<Sequence>().pop_back();
221 typedef boost::multi_index_container<
223 boost::multi_index::indexed_by<
224 boost::multi_index::sequenced<boost::multi_index::tag<Sequence>>,
225 boost::multi_index::hashed_unique<
226 boost::multi_index::tag<Hash>,
227 boost::multi_index::member<Element, Key, &Element::first>,
228 KeyHash>>> Container;
236 auto const& hashContainer = _container.template get<Hash>();
237 auto it = hashContainer.find(
key);
238 bool found = (it != hashContainer.end());
240 _container.relocate(_container.template get<Sequence>().begin(),
241 _container.template project<Sequence>(it));
243 #ifdef LSST_CACHE_DEBUG
244 if (_debuggingEnabled) {
245 _requests.push_back(
key);
254 void _addNew(Key
const&
key, Value
const& value) {
255 _container.template get<Sequence>().emplace_front(
key, value);
260 Container _container;
261 #ifdef LSST_CACHE_DEBUG
262 bool _debuggingEnabled;
274 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
275 template <
typename Generator>
282 return result.first->second;
284 Value value = func(
key);
289 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
293 return result.first->second;
299 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
307 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
311 for (
auto & keyValue : _container.template get<Sequence>()) {
312 result.push_back(keyValue.first);
317 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
320 _container.template get<Sequence>().pop_back();
324 #ifdef LSST_CACHE_DEBUG
325 template <
typename Key,
typename Value,
typename KeyHash,
typename KeyPred>
327 if (!_debuggingEnabled) {
333 for (
auto const&
key : _requests) {
337 std::cerr <<
"Wrote cache requests to " << filename <<
": " << _hits <<
"/" << _total <<
" hits";
345 #endif // ifndef LSST_UTILS_CACHE_H