rippled
Loading...
Searching...
No Matches
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 <xrpl/basics/IntrusivePointer.h>
24#include <xrpl/basics/Log.h>
25#include <xrpl/basics/SharedWeakCachePointer.ipp>
26#include <xrpl/basics/UnorderedContainers.h>
27#include <xrpl/basics/hardened_hash.h>
28#include <xrpl/beast/clock/abstract_clock.h>
29#include <xrpl/beast/insight/Insight.h>
30
31#include <atomic>
32#include <functional>
33#include <mutex>
34#include <thread>
35#include <type_traits>
36#include <vector>
37
38namespace ripple {
39
52template <
53 class Key,
54 class T,
55 bool IsKeyCache = false,
56 class SharedWeakUnionPointerType = SharedWeakCachePointer<T>,
57 class SharedPointerType = std::shared_ptr<T>,
58 class Hash = hardened_hash<>,
59 class KeyEqual = std::equal_to<Key>,
60 class Mutex = std::recursive_mutex>
62{
63public:
64 using mutex_type = Mutex;
65 using key_type = Key;
66 using mapped_type = T;
68 using shared_weak_combo_pointer_type = SharedWeakUnionPointerType;
69 using shared_pointer_type = SharedPointerType;
70
71public:
73 std::string const& name,
74 int size,
75 clock_type::duration expiration,
77 beast::Journal journal,
78 beast::insight::Collector::ptr const& collector =
80
81public:
85
88 size() const;
89
90 int
91 getCacheSize() const;
92
93 float
95
96 void
98
99 void
101
105 template <class KeyComparable>
106 bool
107 touch_if_exists(KeyComparable const& key);
108
110
111 void
113
114 bool
115 del(key_type const& key, bool valid);
116
117public:
131 template <class R>
132 bool
134 key_type const& key,
135 SharedPointerType& data,
136 R&& replaceCallback);
137
138 bool
140 key_type const& key,
141 SharedPointerType const& data);
142
143 bool
144 canonicalize_replace_client(key_type const& key, SharedPointerType& data);
145
146 SharedPointerType
147 fetch(key_type const& key);
148
153 template <class ReturnType = bool>
154 auto
155 insert(key_type const& key, T const& value)
157
158 template <class ReturnType = bool>
159 auto
161
162 // VFALCO NOTE It looks like this returns a copy of the data in
163 // the output parameter 'data'. This could be expensive.
164 // Perhaps it should work like standard containers, which
165 // simply return an iterator.
166 //
167 bool
168 retrieve(key_type const& key, T& data);
169
171 getKeys() const;
172
173 // CachedSLEs functions.
175 double
176 rate() const;
177
183 template <class Handler>
184 SharedPointerType
185 fetch(key_type const& digest, Handler const& h);
186 // End CachedSLEs functions.
187
188private:
189 SharedPointerType
191
192 void
194
195 Mutex&
196 lockPartition(key_type const& key) const;
197
198private:
199 struct Stats
200 {
201 template <class Handler>
203 std::string const& prefix,
204 Handler const& handler,
205 beast::insight::Collector::ptr const& collector)
206 : hook(collector->make_hook(handler))
207 , size(collector->make_gauge(prefix, "size"))
208 , hit_rate(collector->make_gauge(prefix, "hit_rate"))
209 , hits(0)
210 , misses(0)
211 {
212 }
213
217
220 };
221
223 {
224 public:
226
227 explicit KeyOnlyEntry(clock_type::time_point const& last_access_)
228 : last_access(last_access_)
229 {
230 }
231
232 void
234 {
235 last_access = now;
236 }
237 };
238
240 {
241 public:
244
246 clock_type::time_point const& last_access_,
247 shared_pointer_type const& ptr_)
248 : ptr(ptr_), last_access(last_access_)
249 {
250 }
251
252 bool
253 isWeak() const
254 {
255 if (!ptr)
256 return true;
257 return ptr.isWeak();
258 }
259 bool
260 isCached() const
261 {
262 return ptr && ptr.isStrong();
263 }
264 bool
265 isExpired() const
266 {
267 return ptr.expired();
268 }
269 SharedPointerType
271 {
272 return ptr.lock();
273 }
274 void
276 {
277 last_access = now;
278 }
279 };
280
281 typedef
284
287
290
293
294 [[nodiscard]] std::thread
296 clock_type::time_point const& when_expire,
297 [[maybe_unused]] clock_type::time_point const& now,
298 typename KeyValueCacheType::map_type& partition,
299 SweptPointersVector& stuffToSweep,
300 std::atomic<int>& allRemoval,
301 Mutex& partitionLock);
302
303 [[nodiscard]] std::thread
305 clock_type::time_point const& when_expire,
306 clock_type::time_point const& now,
307 typename KeyOnlyCacheType::map_type& partition,
309 std::atomic<int>& allRemovals,
310 Mutex& partitionLock);
311
315
316 // Used for logging
318
319 // Desired number of cache entries (0 = ignore)
320 int const m_target_size;
321
322 // Desired maximum cache age
324
325 // Number of items cached
327 cache_type m_cache; // Hold strong reference to recent objects
331};
332
333} // namespace ripple
334
335#endif
A generic endpoint for log messages.
Definition Journal.h:60
typename Clock::time_point time_point
typename Clock::duration duration
A metric for measuring an integral value.
Definition Gauge.h:40
A reference to a handler for performing polled collection.
Definition Hook.h:32
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
ValueEntry(clock_type::time_point const &last_access_, shared_pointer_type const &ptr_)
shared_weak_combo_pointer_type ptr
clock_type::time_point last_access
void touch(clock_type::time_point const &now)
Map/cache combination.
Definition TaggedCache.h:62
bool canonicalize(key_type const &key, SharedPointerType &data, R &&replaceCallback)
Replace aliased objects with originals.
bool touch_if_exists(KeyComparable const &key)
Refresh the last access time on a key if present.
bool canonicalize_replace_client(key_type const &key, SharedPointerType &data)
bool retrieve(key_type const &key, T &data)
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 > &allRemoval, Mutex &partitionLock)
bool del(key_type const &key, bool valid)
std::atomic< int > m_cache_count
SharedPointerType fetch(key_type const &key)
beast::Journal m_journal
SharedPointerType initialFetch(key_type const &key)
Mutex & lockPartition(key_type const &key) const
clock_type & clock()
Return the clock associated with the cache.
clock_type & m_clock
SharedWeakUnionPointerType shared_weak_combo_pointer_type
Definition TaggedCache.h:68
SharedPointerType fetch(key_type const &digest, Handler const &h)
Fetch an item from the cache.
auto insert(key_type const &key, T const &value) -> std::enable_if_t<!IsKeyCache, ReturnType >
Insert the element into the container.
std::atomic< std::uint64_t > m_misses
std::vector< key_type > getKeys() const
bool canonicalize_replace_cache(key_type const &key, SharedPointerType const &data)
std::size_t size() const
Returns the number of items in 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, Mutex &partitionLock)
int getCacheSize() const
SharedPointerType shared_pointer_type
Definition TaggedCache.h:69
std::conditional< IsKeyCache, KeyOnlyEntry, ValueEntry >::type Entry
double rate() const
Returns the fraction of cache hits.
auto insert(key_type const &key) -> std::enable_if_t< IsKeyCache, ReturnType >
clock_type::duration const m_target_age
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())
int const m_target_size
std::vector< mutex_type > partitionLocks_
std::atomic< std::uint64_t > m_hits
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:25
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition tokens.cpp:156
beast::insight::Gauge size
beast::insight::Hook hook
beast::insight::Gauge hit_rate
Stats(std::string const &prefix, Handler const &handler, beast::insight::Collector::ptr const &collector)