rippled
TaggedCache.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_BASICS_TAGGEDCACHE_H_INCLUDED
21 #define RIPPLE_BASICS_TAGGEDCACHE_H_INCLUDED
22 
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>
28 #include <atomic>
29 #include <functional>
30 #include <mutex>
31 #include <thread>
32 #include <type_traits>
33 #include <vector>
34 
35 namespace ripple {
36 
49 template <
50  class Key,
51  class T,
52  bool IsKeyCache = false,
53  class Hash = hardened_hash<>,
54  class KeyEqual = std::equal_to<Key>,
55  class Mutex = std::recursive_mutex>
56 class TaggedCache
57 {
58 public:
59  using mutex_type = Mutex;
60  using key_type = Key;
61  using mapped_type = T;
63 
64 public:
66  std::string const& name,
67  int size,
68  clock_type::duration expiration,
70  beast::Journal journal,
71  beast::insight::Collector::ptr const& collector =
73  : m_journal(journal)
74  , m_clock(clock)
75  , m_stats(
76  name,
77  std::bind(&TaggedCache::collect_metrics, this),
78  collector)
79  , m_name(name)
81  , m_target_age(expiration)
82  , m_cache_count(0)
83  , m_hits(0)
84  , m_misses(0)
85  {
86  }
87 
88 public:
90  clock_type&
92  {
93  return m_clock;
94  }
95 
98  size() const
99  {
100  std::lock_guard lock(m_mutex);
101  return m_cache.size();
102  }
103 
104  void
106  {
107  std::lock_guard lock(m_mutex);
108  m_target_size = s;
109 
110  if (s > 0)
111  {
112  for (auto& partition : m_cache.map())
113  {
114  partition.rehash(static_cast<std::size_t>(
115  (s + (s >> 2)) /
116  (partition.max_load_factor() * m_cache.partitions()) +
117  1));
118  }
119  }
120 
121  JLOG(m_journal.debug()) << m_name << " target size set to " << s;
122  }
123 
125  getTargetAge() const
126  {
127  std::lock_guard lock(m_mutex);
128  return m_target_age;
129  }
130 
131  void
133  {
134  std::lock_guard lock(m_mutex);
135  m_target_age = s;
136  JLOG(m_journal.debug())
137  << m_name << " target age set to " << m_target_age.count();
138  }
139 
140  int
141  getCacheSize() const
142  {
143  std::lock_guard lock(m_mutex);
144  return m_cache_count;
145  }
146 
147  int
148  getTrackSize() const
149  {
150  std::lock_guard lock(m_mutex);
151  return m_cache.size();
152  }
153 
154  float
156  {
157  std::lock_guard lock(m_mutex);
158  auto const total = static_cast<float>(m_hits + m_misses);
159  return m_hits * (100.0f / std::max(1.0f, total));
160  }
161 
162  void
164  {
165  std::lock_guard lock(m_mutex);
166  m_cache.clear();
167  m_cache_count = 0;
168  }
169 
170  void
172  {
173  std::lock_guard lock(m_mutex);
174  m_cache.clear();
175  m_cache_count = 0;
176  m_hits = 0;
177  m_misses = 0;
178  }
179 
183  template <class KeyComparable>
184  bool
185  touch_if_exists(KeyComparable const& key)
186  {
187  std::lock_guard lock(m_mutex);
188  auto const iter(m_cache.find(key));
189  if (iter == m_cache.end())
190  {
191  ++m_stats.misses;
192  return false;
193  }
194  iter->second.touch(m_clock.now());
195  ++m_stats.hits;
196  return true;
197  }
198 
199  void
201  {
202  // Keep references to all the stuff we sweep
203  // For performance, each worker thread should exit before the swept data
204  // is destroyed but still within the main cache lock.
206  m_cache.partitions());
207 
208  clock_type::time_point const now(m_clock.now());
209  clock_type::time_point when_expire;
210 
211  auto const start = std::chrono::steady_clock::now();
212  {
213  std::lock_guard lock(m_mutex);
214 
215  if (m_target_size == 0 ||
216  (static_cast<int>(m_cache.size()) <= m_target_size))
217  {
218  when_expire = now - m_target_age;
219  }
220  else
221  {
222  when_expire =
224 
225  clock_type::duration const minimumAge(std::chrono::seconds(1));
226  if (when_expire > (now - minimumAge))
227  when_expire = now - minimumAge;
228 
229  JLOG(m_journal.trace())
230  << m_name << " is growing fast " << m_cache.size() << " of "
231  << m_target_size << " aging at "
232  << (now - when_expire).count() << " of "
233  << m_target_age.count();
234  }
235 
236  std::vector<std::thread> workers;
237  workers.reserve(m_cache.partitions());
238  std::atomic<int> allRemovals = 0;
239 
240  for (std::size_t p = 0; p < m_cache.partitions(); ++p)
241  {
242  workers.push_back(sweepHelper(
243  when_expire,
244  now,
245  m_cache.map()[p],
246  allStuffToSweep[p],
247  allRemovals,
248  lock));
249  }
250  for (std::thread& worker : workers)
251  worker.join();
252 
253  m_cache_count -= allRemovals;
254  }
255  // At this point allStuffToSweep will go out of scope outside the lock
256  // and decrement the reference count on each strong pointer.
257  JLOG(m_journal.debug())
258  << m_name << " TaggedCache sweep lock duration "
259  << std::chrono::duration_cast<std::chrono::milliseconds>(
261  .count()
262  << "ms";
263  }
264 
265  bool
266  del(const key_type& key, bool valid)
267  {
268  // Remove from cache, if !valid, remove from map too. Returns true if
269  // removed from cache
270  std::lock_guard lock(m_mutex);
271 
272  auto cit = m_cache.find(key);
273 
274  if (cit == m_cache.end())
275  return false;
276 
277  Entry& entry = cit->second;
278 
279  bool ret = false;
280 
281  if (entry.isCached())
282  {
283  --m_cache_count;
284  entry.ptr.reset();
285  ret = true;
286  }
287 
288  if (!valid || entry.isExpired())
289  m_cache.erase(cit);
290 
291  return ret;
292  }
293 
307 private:
308  template <bool replace>
309  bool
311  const key_type& key,
313  replace,
314  std::shared_ptr<T> const,
315  std::shared_ptr<T>>& data)
316  {
317  // Return canonical value, store if needed, refresh in cache
318  // Return values: true=we had the data already
319  std::lock_guard lock(m_mutex);
320 
321  auto cit = m_cache.find(key);
322 
323  if (cit == m_cache.end())
324  {
326  std::piecewise_construct,
329  ++m_cache_count;
330  return false;
331  }
332 
333  Entry& entry = cit->second;
334  entry.touch(m_clock.now());
335 
336  if (entry.isCached())
337  {
338  if constexpr (replace)
339  {
340  entry.ptr = data;
341  entry.weak_ptr = data;
342  }
343  else
344  {
345  data = entry.ptr;
346  }
347 
348  return true;
349  }
350 
351  auto cachedData = entry.lock();
352 
353  if (cachedData)
354  {
355  if constexpr (replace)
356  {
357  entry.ptr = data;
358  entry.weak_ptr = data;
359  }
360  else
361  {
362  entry.ptr = cachedData;
363  data = cachedData;
364  }
365 
366  ++m_cache_count;
367  return true;
368  }
369 
370  entry.ptr = data;
371  entry.weak_ptr = data;
372  ++m_cache_count;
373 
374  return false;
375  }
376 
377 public:
378  bool
380  const key_type& key,
381  std::shared_ptr<T> const& data)
382  {
383  return canonicalize<true>(key, data);
384  }
385 
386  bool
388  {
389  return canonicalize<false>(key, data);
390  }
391 
393  fetch(const key_type& key)
394  {
396  auto ret = initialFetch(key, l);
397  if (!ret)
398  ++m_misses;
399  return ret;
400  }
401 
406  template <class ReturnType = bool>
407  auto
408  insert(key_type const& key, T const& value)
410  {
411  auto p = std::make_shared<T>(std::cref(value));
412  return canonicalize_replace_client(key, p);
413  }
414 
415  template <class ReturnType = bool>
416  auto
418  {
419  std::lock_guard lock(m_mutex);
420  clock_type::time_point const now(m_clock.now());
421  auto [it, inserted] = m_cache.emplace(
422  std::piecewise_construct,
424  std::forward_as_tuple(now));
425  if (!inserted)
426  it->second.last_access = now;
427  return inserted;
428  }
429 
430  // VFALCO NOTE It looks like this returns a copy of the data in
431  // the output parameter 'data'. This could be expensive.
432  // Perhaps it should work like standard containers, which
433  // simply return an iterator.
434  //
435  bool
436  retrieve(const key_type& key, T& data)
437  {
438  // retrieve the value of the stored data
439  auto entry = fetch(key);
440 
441  if (!entry)
442  return false;
443 
444  data = *entry;
445  return true;
446  }
447 
448  mutex_type&
450  {
451  return m_mutex;
452  }
453 
455  getKeys() const
456  {
458 
459  {
460  std::lock_guard lock(m_mutex);
461  v.reserve(m_cache.size());
462  for (auto const& _ : m_cache)
463  v.push_back(_.first);
464  }
465 
466  return v;
467  }
468 
469  // CachedSLEs functions.
471  double
472  rate() const
473  {
474  std::lock_guard lock(m_mutex);
475  auto const tot = m_hits + m_misses;
476  if (tot == 0)
477  return 0;
478  return double(m_hits) / tot;
479  }
480 
486  template <class Handler>
488  fetch(key_type const& digest, Handler const& h)
489  {
490  {
492  if (auto ret = initialFetch(digest, l))
493  return ret;
494  }
495 
496  auto sle = h();
497  if (!sle)
498  return {};
499 
501  ++m_misses;
502  auto const [it, inserted] =
503  m_cache.emplace(digest, Entry(m_clock.now(), std::move(sle)));
504  if (!inserted)
505  it->second.touch(m_clock.now());
506  return it->second.ptr;
507  }
508  // End CachedSLEs functions.
509 
510 private:
513  {
514  auto cit = m_cache.find(key);
515  if (cit == m_cache.end())
516  return {};
517 
518  Entry& entry = cit->second;
519  if (entry.isCached())
520  {
521  ++m_hits;
522  entry.touch(m_clock.now());
523  return entry.ptr;
524  }
525  entry.ptr = entry.lock();
526  if (entry.isCached())
527  {
528  // independent of cache size, so not counted as a hit
529  ++m_cache_count;
530  entry.touch(m_clock.now());
531  return entry.ptr;
532  }
533 
534  m_cache.erase(cit);
535  return {};
536  }
537 
538  void
540  {
542 
543  {
545  {
546  std::lock_guard lock(m_mutex);
547  auto const total(m_hits + m_misses);
548  if (total != 0)
549  hit_rate = (m_hits * 100) / total;
550  }
551  m_stats.hit_rate.set(hit_rate);
552  }
553  }
554 
555 private:
556  struct Stats
557  {
558  template <class Handler>
560  std::string const& prefix,
561  Handler const& handler,
562  beast::insight::Collector::ptr const& collector)
563  : hook(collector->make_hook(handler))
564  , size(collector->make_gauge(prefix, "size"))
565  , hit_rate(collector->make_gauge(prefix, "hit_rate"))
566  , hits(0)
567  , misses(0)
568  {
569  }
570 
574 
577  };
578 
580  {
581  public:
583 
584  explicit KeyOnlyEntry(clock_type::time_point const& last_access_)
585  : last_access(last_access_)
586  {
587  }
588 
589  void
591  {
592  last_access = now;
593  }
594  };
595 
597  {
598  public:
602 
604  clock_type::time_point const& last_access_,
605  std::shared_ptr<mapped_type> const& ptr_)
606  : ptr(ptr_), weak_ptr(ptr_), last_access(last_access_)
607  {
608  }
609 
610  bool
611  isWeak() const
612  {
613  return ptr == nullptr;
614  }
615  bool
616  isCached() const
617  {
618  return ptr != nullptr;
619  }
620  bool
621  isExpired() const
622  {
623  return weak_ptr.expired();
624  }
627  {
628  return weak_ptr.lock();
629  }
630  void
632  {
633  last_access = now;
634  }
635  };
636 
637  typedef
640 
641  using KeyOnlyCacheType =
643 
644  using KeyValueCacheType =
646 
647  using cache_type =
649 
650  [[nodiscard]] std::thread
652  clock_type::time_point const& when_expire,
653  [[maybe_unused]] clock_type::time_point const& now,
654  typename KeyValueCacheType::map_type& partition,
656  std::atomic<int>& allRemovals,
658  {
659  return std::thread([&, this]() {
660  int cacheRemovals = 0;
661  int mapRemovals = 0;
662 
663  // Keep references to all the stuff we sweep
664  // so that we can destroy them outside the lock.
665  stuffToSweep.reserve(partition.size());
666  {
667  auto cit = partition.begin();
668  while (cit != partition.end())
669  {
670  if (cit->second.isWeak())
671  {
672  // weak
673  if (cit->second.isExpired())
674  {
675  ++mapRemovals;
676  cit = partition.erase(cit);
677  }
678  else
679  {
680  ++cit;
681  }
682  }
683  else if (cit->second.last_access <= when_expire)
684  {
685  // strong, expired
686  ++cacheRemovals;
687  if (cit->second.ptr.unique())
688  {
689  stuffToSweep.push_back(cit->second.ptr);
690  ++mapRemovals;
691  cit = partition.erase(cit);
692  }
693  else
694  {
695  // remains weakly cached
696  cit->second.ptr.reset();
697  ++cit;
698  }
699  }
700  else
701  {
702  // strong, not expired
703  ++cit;
704  }
705  }
706  }
707 
708  if (mapRemovals || cacheRemovals)
709  {
710  JLOG(m_journal.debug())
711  << "TaggedCache partition sweep " << m_name
712  << ": cache = " << partition.size() << "-" << cacheRemovals
713  << ", map-=" << mapRemovals;
714  }
715 
716  allRemovals += cacheRemovals;
717  });
718  }
719 
720  [[nodiscard]] std::thread
722  clock_type::time_point const& when_expire,
723  clock_type::time_point const& now,
724  typename KeyOnlyCacheType::map_type& partition,
726  std::atomic<int>& allRemovals,
728  {
729  return std::thread([&, this]() {
730  int cacheRemovals = 0;
731  int mapRemovals = 0;
732 
733  // Keep references to all the stuff we sweep
734  // so that we can destroy them outside the lock.
735  stuffToSweep.reserve(partition.size());
736  {
737  auto cit = partition.begin();
738  while (cit != partition.end())
739  {
740  if (cit->second.last_access > now)
741  {
742  cit->second.last_access = now;
743  ++cit;
744  }
745  else if (cit->second.last_access <= when_expire)
746  {
747  cit = partition.erase(cit);
748  }
749  else
750  {
751  ++cit;
752  }
753  }
754  }
755 
756  if (mapRemovals || cacheRemovals)
757  {
758  JLOG(m_journal.debug())
759  << "TaggedCache partition sweep " << m_name
760  << ": cache = " << partition.size() << "-" << cacheRemovals
761  << ", map-=" << mapRemovals;
762  }
763 
764  allRemovals += cacheRemovals;
765  });
766  };
767 
768  beast::Journal m_journal;
770  Stats m_stats;
771 
773 
774  // Used for logging
776 
777  // Desired number of cache entries (0 = ignore)
779 
780  // Desired maximum cache age
782 
783  // Number of items cached
785  cache_type m_cache; // Hold strong reference to recent objects
788 };
789 
790 } // namespace ripple
791 
792 #endif
ripple::TaggedCache::getKeys
std::vector< key_type > getKeys() const
Definition: TaggedCache.h:455
ripple::TaggedCache::m_mutex
mutex_type m_mutex
Definition: TaggedCache.h:772
ripple::TaggedCache::fetch
std::shared_ptr< T > fetch(key_type const &digest, Handler const &h)
Fetch an item from the cache.
Definition: TaggedCache.h:488
ripple::TaggedCache::reset
void reset()
Definition: TaggedCache.h:171
std::weak_ptr::lock
T lock(T... args)
ripple::TaggedCache::mutex_type
Mutex mutex_type
Definition: TaggedCache.h:59
ripple::TaggedCache::sweep
void sweep()
Definition: TaggedCache.h:200
ripple::TaggedCache::del
bool del(const key_type &key, bool valid)
Definition: TaggedCache.h:266
ripple::TaggedCache::retrieve
bool retrieve(const key_type &key, T &data)
Definition: TaggedCache.h:436
ripple::TaggedCache::ValueEntry::ValueEntry
ValueEntry(clock_type::time_point const &last_access_, std::shared_ptr< mapped_type > const &ptr_)
Definition: TaggedCache.h:603
ripple::partitioned_unordered_map::size
std::size_t size() const
Definition: partitioned_unordered_map.h:389
std::string
STL class.
std::shared_ptr< Collector >
ripple::TaggedCache
Map/cache combination.
Definition: Application.h:63
beast::Journal::trace
Stream trace() const
Severity stream access functions.
Definition: Journal.h:309
ripple::partitioned_unordered_map::clear
void clear()
Definition: partitioned_unordered_map.h:364
ripple::partitioned_unordered_map::map
partition_map_type & map()
Definition: partitioned_unordered_map.h:259
functional
ripple::TaggedCache::ValueEntry::isCached
bool isCached() const
Definition: TaggedCache.h:616
ripple::TaggedCache::insert
auto insert(key_type const &key) -> std::enable_if_t< IsKeyCache, ReturnType >
Definition: TaggedCache.h:417
ripple::partitioned_unordered_map::end
static void end(T &it)
Definition: partitioned_unordered_map.h:219
std::vector::reserve
T reserve(T... args)
vector
ripple::TaggedCache::clear
void clear()
Definition: TaggedCache.h:163
ripple::TaggedCache::m_cache
cache_type m_cache
Definition: TaggedCache.h:785
std::chrono::seconds
std::recursive_mutex
STL class.
ripple::TaggedCache::m_cache_count
int m_cache_count
Definition: TaggedCache.h:784
std::lock_guard
STL class.
ripple::TaggedCache::ValueEntry
Definition: TaggedCache.h:596
ripple::TaggedCache::collect_metrics
void collect_metrics()
Definition: TaggedCache.h:539
ripple::TaggedCache::Stats::hook
beast::insight::Hook hook
Definition: TaggedCache.h:571
ripple::partitioned_unordered_map
Definition: partitioned_unordered_map.h:43
ripple::TaggedCache< uint256, SLE const >::mapped_type
SLE const mapped_type
Definition: TaggedCache.h:61
ripple::TaggedCache::sweepHelper
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)
Definition: TaggedCache.h:721
ripple::partitioned_unordered_map::find
void find(key_type const &key, T &it) const
Definition: partitioned_unordered_map.h:311
ripple::partitioned_unordered_map::partitions
std::size_t partitions() const
Definition: partitioned_unordered_map.h:253
ripple::TaggedCache::ValueEntry::touch
void touch(clock_type::time_point const &now)
Definition: TaggedCache.h:631
ripple::TaggedCache::ValueEntry::weak_ptr
std::weak_ptr< mapped_type > weak_ptr
Definition: TaggedCache.h:600
ripple::TaggedCache::m_misses
std::uint64_t m_misses
Definition: TaggedCache.h:787
ripple::TaggedCache::canonicalize_replace_cache
bool canonicalize_replace_cache(const key_type &key, std::shared_ptr< T > const &data)
Definition: TaggedCache.h:379
ripple::TaggedCache::Stats::size
beast::insight::Gauge size
Definition: TaggedCache.h:572
std::weak_ptr::expired
T expired(T... args)
beast::abstract_clock::now
virtual time_point now() const =0
Returns the current time.
std::vector::push_back
T push_back(T... args)
ripple::digest
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition: tokens.cpp:47
ripple::TaggedCache::getHitRate
float getHitRate()
Definition: TaggedCache.h:155
ripple::base_uint< 256 >
ripple::TaggedCache::KeyOnlyEntry::last_access
clock_type::time_point last_access
Definition: TaggedCache.h:582
ripple::TaggedCache::setTargetSize
void setTargetSize(int s)
Definition: TaggedCache.h:105
ripple::TaggedCache::m_target_age
clock_type::duration m_target_age
Definition: TaggedCache.h:781
ripple::TaggedCache::getTrackSize
int getTrackSize() const
Definition: TaggedCache.h:148
thread
ripple::TaggedCache::setTargetAge
void setTargetAge(clock_type::duration s)
Definition: TaggedCache.h:132
ripple::TaggedCache::sweepHelper
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)
Definition: TaggedCache.h:651
std::enable_if_t
ripple::TaggedCache::insert
auto insert(key_type const &key, T const &value) -> std::enable_if_t<!IsKeyCache, ReturnType >
Insert the element into the container.
Definition: TaggedCache.h:408
ripple::TaggedCache::Stats::misses
std::size_t misses
Definition: TaggedCache.h:576
ripple::TaggedCache::Stats::hit_rate
beast::insight::Gauge hit_rate
Definition: TaggedCache.h:573
ripple::TaggedCache::ValueEntry::isExpired
bool isExpired() const
Definition: TaggedCache.h:621
ripple::TaggedCache::Stats::hits
std::size_t hits
Definition: TaggedCache.h:575
ripple::TaggedCache::ValueEntry::lock
std::shared_ptr< mapped_type > lock()
Definition: TaggedCache.h:626
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
std::uint64_t
ripple::TaggedCache::KeyOnlyEntry::touch
void touch(clock_type::time_point const &now)
Definition: TaggedCache.h:590
ripple::TaggedCache::Stats
Definition: TaggedCache.h:556
atomic
std::forward_as_tuple
T forward_as_tuple(T... args)
ripple::TaggedCache::Stats::Stats
Stats(std::string const &prefix, Handler const &handler, beast::insight::Collector::ptr const &collector)
Definition: TaggedCache.h:559
ripple::TaggedCache::rate
double rate() const
Returns the fraction of cache hits.
Definition: TaggedCache.h:472
ripple::partitioned_unordered_map::emplace
std::pair< iterator, bool > emplace(std::piecewise_construct_t const &, T &&keyTuple, U &&valueTuple)
Definition: partitioned_unordered_map.h:338
ripple::partitioned_unordered_map::erase
iterator erase(const_iterator position)
Definition: partitioned_unordered_map.h:371
ripple::TaggedCache::getCacheSize
int getCacheSize() const
Definition: TaggedCache.h:141
beast::abstract_clock< std::chrono::steady_clock >
ripple::TaggedCache::size
std::size_t size() const
Returns the number of items in the container.
Definition: TaggedCache.h:98
beast::insight::Gauge
A metric for measuring an integral value.
Definition: Gauge.h:39
std::weak_ptr< mapped_type >
std::equal_to
ripple::TaggedCache::m_hits
std::uint64_t m_hits
Definition: TaggedCache.h:786
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::TaggedCache::clock_type
beast::abstract_clock< std::chrono::steady_clock > clock_type
Definition: TaggedCache.h:62
ripple::TaggedCache< uint256, SLE const >::Entry
std::conditional< false, KeyOnlyEntry, ValueEntry >::type Entry
Definition: TaggedCache.h:639
ripple::TaggedCache::m_name
std::string m_name
Definition: TaggedCache.h:775
ripple::TaggedCache::canonicalize
bool canonicalize(const key_type &key, std::conditional_t< replace, std::shared_ptr< T > const, std::shared_ptr< T >> &data)
Replace aliased objects with originals.
Definition: TaggedCache.h:310
ripple::TaggedCache::KeyOnlyEntry
Definition: TaggedCache.h:579
ripple::TaggedCache::fetch
std::shared_ptr< T > fetch(const key_type &key)
Definition: TaggedCache.h:393
std
STL namespace.
ripple::TaggedCache::ValueEntry::last_access
clock_type::time_point last_access
Definition: TaggedCache.h:601
ripple::TaggedCache::m_journal
beast::Journal m_journal
Definition: TaggedCache.h:766
ripple::TaggedCache::KeyOnlyEntry::KeyOnlyEntry
KeyOnlyEntry(clock_type::time_point const &last_access_)
Definition: TaggedCache.h:584
mutex
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
std::size_t
ripple::TaggedCache::touch_if_exists
bool touch_if_exists(KeyComparable const &key)
Refresh the last access time on a key if present.
Definition: TaggedCache.h:185
ripple::TaggedCache::canonicalize_replace_client
bool canonicalize_replace_client(const key_type &key, std::shared_ptr< T > &data)
Definition: TaggedCache.h:387
ripple::TaggedCache::peekMutex
mutex_type & peekMutex()
Definition: TaggedCache.h:449
std::conditional_t
std::max
T max(T... args)
ripple::TaggedCache::ValueEntry::ptr
std::shared_ptr< mapped_type > ptr
Definition: TaggedCache.h:599
ripple::TaggedCache::initialFetch
std::shared_ptr< T > initialFetch(key_type const &key, std::lock_guard< mutex_type > const &l)
Definition: TaggedCache.h:512
ripple::TaggedCache::getTargetAge
clock_type::duration getTargetAge() const
Definition: TaggedCache.h:125
ripple::TaggedCache::m_target_size
int m_target_size
Definition: TaggedCache.h:778
std::unordered_map
STL class.
ripple::TaggedCache::m_stats
Stats m_stats
Definition: TaggedCache.h:770
beast::abstract_clock< std::chrono::steady_clock >::time_point
typename std::chrono::steady_clock ::time_point time_point
Definition: abstract_clock.h:63
beast::insight::Hook
A reference to a handler for performing polled collection.
Definition: Hook.h:31
type_traits
beast::insight::NullCollector::New
static std::shared_ptr< Collector > New()
Definition: NullCollector.cpp:152
beast::abstract_clock< std::chrono::steady_clock >::duration
typename std::chrono::steady_clock ::duration duration
Definition: abstract_clock.h:62
ripple::TaggedCache::m_clock
clock_type & m_clock
Definition: TaggedCache.h:769
std::cref
T cref(T... args)
std::thread::join
T join(T... args)
beast::insight::Gauge::set
void set(value_type value) const
Set the value on the gauge.
Definition: Gauge.h:68
ripple::TaggedCache::clock
clock_type & clock()
Return the clock associated with the cache.
Definition: TaggedCache.h:91
ripple::TaggedCache::TaggedCache
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())
Definition: TaggedCache.h:65
ripple::TaggedCache::ValueEntry::isWeak
bool isWeak() const
Definition: TaggedCache.h:611
std::chrono::steady_clock::now
T now(T... args)