20 #ifndef RIPPLE_BASICS_TAGGEDCACHE_H_INCLUDED
21 #define RIPPLE_BASICS_TAGGEDCACHE_H_INCLUDED
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/UnorderedContainers.h>
25 #include <ripple/basics/hardened_hash.h>
26 #include <ripple/beast/clock/abstract_clock.h>
27 #include <ripple/beast/insight/Insight.h>
52 bool IsKeyCache =
false,
53 class Hash = hardened_hash<>,
183 template <
class KeyComparable>
226 if (when_expire > (now - minimumAge))
227 when_expire = now - minimumAge;
232 << (now - when_expire).count() <<
" of "
258 <<
m_name <<
" TaggedCache sweep lock duration "
259 << std::chrono::duration_cast<std::chrono::milliseconds>(
277 Entry& entry = cit->second;
281 if (entry.isCached())
288 if (!valid || entry.isExpired())
323 std::piecewise_construct,
330 Entry& entry = cit->second;
333 if (entry.isCached())
335 if (replace(entry.ptr))
338 entry.weak_ptr = data;
348 auto cachedData = entry.lock();
352 if (replace(entry.ptr))
355 entry.weak_ptr = data;
359 entry.ptr = cachedData;
368 entry.weak_ptr = data;
406 template <
class ReturnType =
bool>
411 auto p = std::make_shared<T>(
std::cref(value));
415 template <
class ReturnType =
bool>
422 std::piecewise_construct,
426 it->second.last_access = now;
439 auto entry =
fetch(key);
478 return double(
m_hits) / tot;
486 template <
class Handler>
502 auto const [it, inserted] =
506 return it->second.ptr;
518 Entry& entry = cit->second;
519 if (entry.isCached())
525 entry.ptr = entry.lock();
526 if (entry.isCached())
549 hit_rate = (
m_hits * 100) / total;
558 template <
class Handler>
561 Handler
const& handler,
563 :
hook(collector->make_hook(handler))
564 ,
size(collector->make_gauge(prefix,
"size"))
565 ,
hit_rate(collector->make_gauge(prefix,
"hit_rate"))
613 return ptr ==
nullptr;
618 return ptr !=
nullptr;
660 int cacheRemovals = 0;
665 stuffToSweep.reserve(partition.size());
667 auto cit = partition.begin();
668 while (cit != partition.end())
670 if (cit->second.isWeak())
673 if (cit->second.isExpired())
676 cit = partition.erase(cit);
683 else if (cit->second.last_access <= when_expire)
687 if (cit->second.ptr.unique())
689 stuffToSweep.push_back(cit->second.ptr);
691 cit = partition.erase(cit);
696 cit->second.ptr.reset();
708 if (mapRemovals || cacheRemovals)
711 <<
"TaggedCache partition sweep " <<
m_name
712 <<
": cache = " << partition.size() <<
"-" << cacheRemovals
713 <<
", map-=" << mapRemovals;
716 allRemovals += cacheRemovals;
730 int cacheRemovals = 0;
735 stuffToSweep.reserve(partition.size());
737 auto cit = partition.begin();
738 while (cit != partition.end())
740 if (cit->second.last_access > now)
742 cit->second.last_access = now;
745 else if (cit->second.last_access <= when_expire)
747 cit = partition.erase(cit);
756 if (mapRemovals || cacheRemovals)
758 JLOG(m_journal.debug())
759 <<
"TaggedCache partition sweep " << m_name
760 <<
": cache = " << partition.size() <<
"-" << cacheRemovals
761 <<
", map-=" << mapRemovals;
764 allRemovals += cacheRemovals;
std::vector< key_type > getKeys() const
std::shared_ptr< T > fetch(key_type const &digest, Handler const &h)
Fetch an item from the cache.
bool del(const key_type &key, bool valid)
bool retrieve(const key_type &key, T &data)
ValueEntry(clock_type::time_point const &last_access_, std::shared_ptr< mapped_type > const &ptr_)
Stream trace() const
Severity stream access functions.
partition_map_type & map()
auto insert(key_type const &key) -> std::enable_if_t< IsKeyCache, ReturnType >
beast::insight::Hook hook
std::thread sweepHelper(clock_type::time_point const &when_expire, clock_type::time_point const &now, typename KeyOnlyCacheType::map_type &partition, std::vector< std::shared_ptr< mapped_type >> &stuffToSweep, std::atomic< int > &allRemovals, std::lock_guard< std::recursive_mutex > const &lock)
void find(key_type const &key, T &it) const
std::size_t partitions() const
void touch(clock_type::time_point const &now)
std::weak_ptr< mapped_type > weak_ptr
bool canonicalize_replace_cache(const key_type &key, std::shared_ptr< T > const &data)
beast::insight::Gauge size
virtual time_point now() const =0
Returns the current time.
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
clock_type::time_point last_access
bool canonicalize(const key_type &key, std::shared_ptr< T > &data, std::function< bool(std::shared_ptr< T > const &)> &&replace)
Replace aliased objects with originals.
void setTargetSize(int s)
clock_type::duration m_target_age
void setTargetAge(clock_type::duration s)
std::thread sweepHelper(clock_type::time_point const &when_expire, [[maybe_unused]] clock_type::time_point const &now, typename KeyValueCacheType::map_type &partition, std::vector< std::shared_ptr< mapped_type >> &stuffToSweep, std::atomic< int > &allRemovals, std::lock_guard< std::recursive_mutex > const &lock)
auto insert(key_type const &key, T const &value) -> std::enable_if_t<!IsKeyCache, ReturnType >
Insert the element into the container.
beast::insight::Gauge hit_rate
std::shared_ptr< mapped_type > lock()
A generic endpoint for log messages.
void touch(clock_type::time_point const &now)
T forward_as_tuple(T... args)
Stats(std::string const &prefix, Handler const &handler, beast::insight::Collector::ptr const &collector)
double rate() const
Returns the fraction of cache hits.
std::pair< iterator, bool > emplace(std::piecewise_construct_t const &, T &&keyTuple, U &&valueTuple)
iterator erase(const_iterator position)
std::size_t size() const
Returns the number of items in the container.
A metric for measuring an integral value.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
beast::abstract_clock< std::chrono::steady_clock > clock_type
std::conditional< false, KeyOnlyEntry, ValueEntry >::type Entry
std::shared_ptr< T > fetch(const key_type &key)
clock_type::time_point last_access
KeyOnlyEntry(clock_type::time_point const &last_access_)
bool touch_if_exists(KeyComparable const &key)
Refresh the last access time on a key if present.
bool canonicalize_replace_client(const key_type &key, std::shared_ptr< T > &data)
std::shared_ptr< mapped_type > ptr
std::shared_ptr< T > initialFetch(key_type const &key, std::lock_guard< mutex_type > const &l)
clock_type::duration getTargetAge() const
typename std::chrono::steady_clock ::time_point time_point
A reference to a handler for performing polled collection.
static std::shared_ptr< Collector > New()
typename std::chrono::steady_clock ::duration duration
void set(value_type value) const
Set the value on the gauge.
clock_type & clock()
Return the clock associated with the cache.
TaggedCache(std::string const &name, int size, clock_type::duration expiration, clock_type &clock, beast::Journal journal, beast::insight::Collector::ptr const &collector=beast::insight::NullCollector::New())