Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
SynchronizedCallerStalenessCache.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
6
7 /*
8 ********************************************************************************
9 ******** SynchronizedCallerStalenessCache<KEY, VALUE, TIME_TRAITS> *************
10 ********************************************************************************
11 */
12 template <typename KEY, typename VALUE, typename TIME_TRAITS>
14 {
15 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
16 inherited::ClearOlderThan (t);
17 }
18 template <typename KEY, typename VALUE, typename TIME_TRAITS>
20 {
21 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
22 inherited::Clear ();
23 }
24 template <typename KEY, typename VALUE, typename TIME_TRAITS>
25 template <typename K1>
27 requires (IsKeyedCache<K1>)
28 {
29 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
30 inherited::Clear (k);
31 }
32 template <typename KEY, typename VALUE, typename TIME_TRAITS>
34 requires (not IsKeyedCache<KEY>)
35 {
36 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
37 inherited::Add (v);
38 }
39 template <typename KEY, typename VALUE, typename TIME_TRAITS>
40 template <typename K>
42 AddReplaceMode addReplaceMode)
43 requires (IsKeyedCache<K>)
44 {
45 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
46 inherited::Add (k, v, addReplaceMode);
47 }
48 template <typename KEY, typename VALUE, typename TIME_TRAITS>
50 requires (not IsKeyedCache<KEY>)
51 {
52 [[maybe_unused]] auto&& lock = shared_lock{fMutex_};
53 return inherited::Lookup (staleIfOlderThan);
54 }
55 template <typename KEY, typename VALUE, typename TIME_TRAITS>
56 template <typename K>
58 requires (IsKeyedCache<K>)
59 {
60 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
61 return inherited::Lookup (k, staleIfOlderThan);
62 }
63 template <typename KEY, typename VALUE, typename TIME_TRAITS>
64 inline VALUE SynchronizedCallerStalenessCache<KEY, VALUE, TIME_TRAITS>::LookupValue (TimeStampType staleIfOlderThan, const function<VALUE ()>& cacheFiller)
65 requires (not IsKeyedCache<KEY>)
66 {
67 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
68 return inherited::LookupValue (staleIfOlderThan, cacheFiller);
69 }
70 template <typename KEY, typename VALUE, typename TIME_TRAITS>
71 template <typename F, typename K>
72 inline VALUE SynchronizedCallerStalenessCache<KEY, VALUE, TIME_TRAITS>::LookupValue (Common::ArgByValueType<K> k,
73 TimeStampType staleIfOlderThan, F&& cacheFiller)
74 requires (IsKeyedCache<KEY> and is_invocable_r_v<VALUE, F, KEY>)
75 {
76 /*
77 * The main reason for this class, is this logic: unlocking the shared lock and then fetching the new value (with a write lock).
78 */
79 auto&& lock = shared_lock{fMutex_};
80 if (optional<VALUE> o = inherited::Lookup (k, staleIfOlderThan)) {
81 return *o;
82 }
83 else {
84 lock.unlock ();
85 if (fHoldWriteLockDuringCacheFill) {
86 // Avoid two threads calling cache filler for same key value at the same time
87 [[maybe_unused]] auto&& newRWLock = lock_guard{fMutex_};
88 VALUE v = cacheFiller (k);
89 inherited::Add (k, v);
90 return v;
91 }
92 else {
93 // Avoid needlessly blocking lookups (shared_lock above) until after we've filled the cache (typically slow)
94 // and keep it to minimum logically required (inherited add).
95 VALUE v = cacheFiller (k);
96 Add (k, v);
97 return v;
98 }
99 }
100 }
101 template <typename KEY, typename VALUE, typename TIME_TRAITS>
102 template <typename K>
104 const VALUE& defaultValue) const
105 requires (IsKeyedCache<KEY>)
106 {
107 [[maybe_unused]] auto&& lock = shared_lock{fMutex_}; // ignore fHoldWriteLockDuringCacheFill since this is always fast; shared cuz doesn't update cache
108 return inherited::LookupValue (k, staleIfOlderThan, defaultValue);
109 }
110 template <typename KEY, typename VALUE, typename TIME_TRAITS>
113 [[maybe_unused]] auto&& lock = lock_guard{fMutex_};
114 inherited::clear ();
115 }
116
117}
LRUCache implements a simple least-recently-used caching strategy, with optional hashing (of keys) to...
Definition LRUCache.h:94
simple wrapper on CallerStalenessCache (with the same API) - but internally synchronized in a way tha...
nonvirtual optional< VALUE > Lookup(TimeStampType staleIfOlderThan) const
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
Definition TypeHints.h:32