rippled
Loading...
Searching...
No Matches
TaggedCache.h
1#pragma once
2
3#include <xrpl/basics/IntrusivePointer.h>
4#include <xrpl/basics/Log.h>
5#include <xrpl/basics/SharedWeakCachePointer.ipp>
6#include <xrpl/basics/UnorderedContainers.h>
7#include <xrpl/basics/hardened_hash.h>
8#include <xrpl/beast/clock/abstract_clock.h>
9#include <xrpl/beast/insight/Insight.h>
10
11#include <atomic>
12#include <functional>
13#include <mutex>
14#include <thread>
15#include <type_traits>
16#include <vector>
17
18namespace xrpl {
19
32template <
33 class Key,
34 class T,
35 bool IsKeyCache = false,
36 class SharedWeakUnionPointerType = SharedWeakCachePointer<T>,
37 class SharedPointerType = std::shared_ptr<T>,
38 class Hash = hardened_hash<>,
39 class KeyEqual = std::equal_to<Key>,
40 class Mutex = std::recursive_mutex>
42{
43public:
44 using mutex_type = Mutex;
45 using key_type = Key;
46 using mapped_type = T;
48 using shared_weak_combo_pointer_type = SharedWeakUnionPointerType;
49 using shared_pointer_type = SharedPointerType;
50
51public:
53 std::string const& name,
54 int size,
55 clock_type::duration expiration,
57 beast::Journal journal,
59
60public:
64
67 size() const;
68
69 int
70 getCacheSize() const;
71
72 int
73 getTrackSize() const;
74
75 float
77
78 void
80
81 void
83
87 template <class KeyComparable>
88 bool
89 touch_if_exists(KeyComparable const& key);
90
92
93 void
95
96 bool
97 del(key_type const& key, bool valid);
98
99public:
113 template <class R>
114 bool
115 canonicalize(key_type const& key, SharedPointerType& data, R&& replaceCallback);
116
117 bool
118 canonicalize_replace_cache(key_type const& key, SharedPointerType const& data);
119
120 bool
121 canonicalize_replace_client(key_type const& key, SharedPointerType& data);
122
123 SharedPointerType
124 fetch(key_type const& key);
125
130 template <class ReturnType = bool>
131 auto
133
134 template <class ReturnType = bool>
135 auto
137
138 // VFALCO NOTE It looks like this returns a copy of the data in
139 // the output parameter 'data'. This could be expensive.
140 // Perhaps it should work like standard containers, which
141 // simply return an iterator.
142 //
143 bool
144 retrieve(key_type const& key, T& data);
145
148
150 getKeys() const;
151
152 // CachedSLEs functions.
154 double
155 rate() const;
156
162 template <class Handler>
163 SharedPointerType
164 fetch(key_type const& digest, Handler const& h);
165 // End CachedSLEs functions.
166
167private:
168 SharedPointerType
170
171 void
173
174private:
175 struct Stats
176 {
177 template <class Handler>
178 Stats(std::string const& prefix, Handler const& handler, beast::insight::Collector::ptr const& collector)
179 : hook(collector->make_hook(handler))
180 , size(collector->make_gauge(prefix, "size"))
181 , hit_rate(collector->make_gauge(prefix, "hit_rate"))
182 , hits(0)
183 , misses(0)
184 {
185 }
186
190
193 };
194
196 {
197 public:
199
200 explicit KeyOnlyEntry(clock_type::time_point const& last_access_) : last_access(last_access_)
201 {
202 }
203
204 void
206 {
207 last_access = now;
208 }
209 };
210
212 {
213 public:
216
217 ValueEntry(clock_type::time_point const& last_access_, shared_pointer_type const& ptr_)
218 : ptr(ptr_), last_access(last_access_)
219 {
220 }
221
222 bool
223 isWeak() const
224 {
225 if (!ptr)
226 return true;
227 return ptr.isWeak();
228 }
229 bool
230 isCached() const
231 {
232 return ptr && ptr.isStrong();
233 }
234 bool
235 isExpired() const
236 {
237 return ptr.expired();
238 }
239 SharedPointerType
241 {
242 return ptr.lock();
243 }
244 void
246 {
247 last_access = now;
248 }
249 };
250
252
254
256
258
259 [[nodiscard]] std::thread
261 clock_type::time_point const& when_expire,
262 [[maybe_unused]] clock_type::time_point const& now,
263 typename KeyValueCacheType::map_type& partition,
264 SweptPointersVector& stuffToSweep,
265 std::atomic<int>& allRemovals,
267
268 [[nodiscard]] std::thread
270 clock_type::time_point const& when_expire,
271 clock_type::time_point const& now,
272 typename KeyOnlyCacheType::map_type& partition,
274 std::atomic<int>& allRemovals,
276
280
282
283 // Used for logging
285
286 // Desired number of cache entries (0 = ignore)
287 int const m_target_size;
288
289 // Desired maximum cache age
291
292 // Number of items cached
294 cache_type m_cache; // Hold strong reference to recent objects
297};
298
299} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
typename Clock::time_point time_point
typename Clock::duration duration
A metric for measuring an integral value.
Definition Gauge.h:20
A reference to a handler for performing polled collection.
Definition Hook.h:12
static std::shared_ptr< Collector > New()
void touch(clock_type::time_point const &now)
KeyOnlyEntry(clock_type::time_point const &last_access_)
clock_type::time_point last_access
SharedPointerType lock()
void touch(clock_type::time_point const &now)
shared_weak_combo_pointer_type ptr
ValueEntry(clock_type::time_point const &last_access_, shared_pointer_type const &ptr_)
clock_type::time_point last_access
Map/cache combination.
Definition TaggedCache.h:42
SharedPointerType shared_pointer_type
Definition TaggedCache.h:49
std::vector< key_type > getKeys() const
std::conditional< IsKeyCache, KeyOnlyEntry, ValueEntry >::type Entry
bool del(key_type const &key, bool valid)
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())
bool retrieve(key_type const &key, T &data)
int getTrackSize() const
int getCacheSize() const
clock_type & m_clock
std::thread sweepHelper(clock_type::time_point const &when_expire, clock_type::time_point const &now, typename KeyValueCacheType::map_type &partition, SweptPointersVector &stuffToSweep, std::atomic< int > &allRemovals, std::lock_guard< std::recursive_mutex > const &)
SharedPointerType initialFetch(key_type const &key, std::lock_guard< mutex_type > const &l)
auto insert(key_type const &key, T const &value) -> std::enable_if_t<!IsKeyCache, ReturnType >
Insert the element into the container.
std::thread sweepHelper(clock_type::time_point const &when_expire, clock_type::time_point const &now, typename KeyOnlyCacheType::map_type &partition, SweptPointersVector &, std::atomic< int > &allRemovals, std::lock_guard< std::recursive_mutex > const &)
clock_type::duration const m_target_age
SharedWeakUnionPointerType shared_weak_combo_pointer_type
Definition TaggedCache.h:48
std::size_t size() const
Returns the number of items in the container.
std::uint64_t m_hits
mutex_type m_mutex
bool canonicalize_replace_cache(key_type const &key, SharedPointerType const &data)
int const m_target_size
SharedPointerType fetch(key_type const &digest, Handler const &h)
Fetch an item from the cache.
auto insert(key_type const &key) -> std::enable_if_t< IsKeyCache, ReturnType >
cache_type m_cache
bool canonicalize_replace_client(key_type const &key, SharedPointerType &data)
bool touch_if_exists(KeyComparable const &key)
Refresh the last access time on a key if present.
clock_type & clock()
Return the clock associated with the cache.
SharedPointerType fetch(key_type const &key)
bool canonicalize(key_type const &key, SharedPointerType &data, R &&replaceCallback)
Replace aliased objects with originals.
double rate() const
Returns the fraction of cache hits.
std::string m_name
std::uint64_t m_misses
beast::Journal m_journal
mutex_type & peekMutex()
TER valid(STTx const &tx, ReadView const &view, AccountID const &src, beast::Journal j)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition tokens.cpp:137
Stats(std::string const &prefix, Handler const &handler, beast::insight::Collector::ptr const &collector)
beast::insight::Gauge size
beast::insight::Hook hook
beast::insight::Gauge hit_rate