#ifndef ADHOCUTIL_CACHE_H #define ADHOCUTIL_CACHE_H #include #include #include #include #include #include #include #include namespace AdHoc { /// @cond template class Cacheable { public: Cacheable(const K & k, time_t validUntil); const K key; const time_t validUntil; virtual const T & item() const = 0; }; template class ObjectCacheable : public Cacheable { public: ObjectCacheable(const T & t, const K & k, time_t validUtil); virtual const T & item() const override; private: const T value; }; template class CallCacheable : public Cacheable { public: CallCacheable(const T & t, const K & k, time_t validUtil); CallCacheable(const boost::function & t, const K & k, time_t validUtil); virtual const T & item() const override; private: mutable boost::variant> value; mutable boost::shared_mutex lock; }; struct byValidity {}; struct byKey {}; /// @endcond /// In-memory cache of T, keyed by K. template class Cache { public: /// @cond typedef K Key; typedef T Value; typedef Cacheable Item; typedef boost::shared_ptr Element; /// @endcond /** Construct a default empty cache. */ Cache(); /** Add a known item to the cache. * @param k The key of the cache item. * @param t The item to cache. * @param validUntil The absolute time the cache item should expire. */ void add(const K & k, const T & t, time_t validUntil); /** Add a callback item to the cache. * The callback will be called on first hit of the cache item, at which * point the return value of the function will be cached. * @param k The key of the cache item. * @param tf The callback function to cache. * @param validUntil The absolute time the cache item should expire. */ void add(const K & k, const boost::function & tf, time_t validUntil); /** Get an Element from the cache. The element represents the key, item and expiry time. * Returns null on cache-miss. * @param k Cache key to get. */ Element getItem(const K & k) const; /** Get an Item from the cache. Returns null on cache-miss. * @param k Cache key to get. */ const T * get(const K & k) const; /** Get the size of the cache (number of items). @warning This cannot be reliably used to * determine or estimate the amount of memory used by items in the cache without further * knowledge of the items themselves. */ size_t size() const; private: void prune() const; mutable time_t lastPruneTime; mutable boost::shared_mutex lock; typedef boost::multi_index::multi_index_container, BOOST_MULTI_INDEX_MEMBER(Item, const K, key)>, boost::multi_index::ordered_non_unique< boost::multi_index::tag, BOOST_MULTI_INDEX_MEMBER(Item, const time_t, validUntil)> > > Cached; mutable Cached cached; }; } #endif