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>
179 std::string const& prefix,
180 Handler const& handler,
181 beast::insight::Collector::ptr const& collector)
182 : hook(collector->make_hook(handler))
183 , size(collector->make_gauge(prefix, "size"))
184 , hit_rate(collector->make_gauge(prefix, "hit_rate"))
185
186 {
187 }
188
192
195 };
196
198 {
199 public:
201
202 explicit KeyOnlyEntry(clock_type::time_point const& last_access_)
203 : last_access(last_access_)
204 {
205 }
206
207 void
209 {
210 last_access = now;
211 }
212 };
213
215 {
216 public:
219
220 ValueEntry(clock_type::time_point const& last_access_, shared_pointer_type const& ptr_)
221 : ptr(ptr_), last_access(last_access_)
222 {
223 }
224
225 bool
226 isWeak() const
227 {
228 if (!ptr)
229 return true;
230 return ptr.isWeak();
231 }
232 bool
233 isCached() const
234 {
235 return ptr && ptr.isStrong();
236 }
237 bool
238 isExpired() const
239 {
240 return ptr.expired();
241 }
242 SharedPointerType
244 {
245 return ptr.lock();
246 }
247 void
249 {
250 last_access = now;
251 }
252 };
253
255
257
259
261
262 [[nodiscard]] std::thread
264 clock_type::time_point const& when_expire,
265 [[maybe_unused]] clock_type::time_point const& now,
266 typename KeyValueCacheType::map_type& partition,
267 SweptPointersVector& stuffToSweep,
268 std::atomic<int>& allRemovals,
270
271 [[nodiscard]] std::thread
273 clock_type::time_point const& when_expire,
274 clock_type::time_point const& now,
275 typename KeyOnlyCacheType::map_type& partition,
277 std::atomic<int>& allRemovals,
279
283
285
286 // Used for logging
288
289 // Desired number of cache entries (0 = ignore)
290 int const m_target_size;
291
292 // Desired maximum cache age
294
295 // Number of items cached
297 cache_type m_cache; // Hold strong reference to recent objects
300};
301
302} // 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:138
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