CppCommon  1.0.4.1
C++ Common Library
memcache.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template <typename TKey, typename TValue>
12 inline bool MemCache<TKey, TValue>::empty() const
13 {
14  std::shared_lock<std::shared_mutex> locker(_lock);
15  return _entries_by_key.empty();
16 }
17 
18 template <typename TKey, typename TValue>
19 inline size_t MemCache<TKey, TValue>::size() const
20 {
21  std::shared_lock<std::shared_mutex> locker(_lock);
22  return _entries_by_key.size();
23 }
24 
25 template <typename TKey, typename TValue>
26 inline bool MemCache<TKey, TValue>::emplace(TKey&& key, TValue&& value, const Timespan& timeout)
27 {
28  std::unique_lock<std::shared_mutex> locker(_lock);
29 
30  // Try to find and remove the previous key
31  remove_internal(key);
32 
33  // Update the cache entry
34  if (timeout.total() > 0)
35  {
36  Timestamp current = UtcTimestamp();
37  _timestamp = (current <= _timestamp) ? _timestamp + 1 : current;
38  _entries_by_key.insert(std::make_pair(key, MemCacheEntry(std::move(value), _timestamp, timeout)));
39  _entries_by_timestamp.insert(std::make_pair(_timestamp, key));
40  }
41  else
42  _entries_by_key.emplace(std::make_pair(std::move(key), MemCacheEntry(std::move(value))));
43 
44  return true;
45 }
46 
47 template <typename TKey, typename TValue>
48 inline bool MemCache<TKey, TValue>::insert(const TKey& key, const TValue& value, const Timespan& timeout)
49 {
50  std::unique_lock<std::shared_mutex> locker(_lock);
51 
52  // Try to find and remove the previous key
53  remove_internal(key);
54 
55  // Update the cache entry
56  if (timeout.total() > 0)
57  {
58  Timestamp current = UtcTimestamp();
59  _timestamp = (current <= _timestamp) ? _timestamp + 1 : current;
60  _entries_by_key.insert(std::make_pair(key, MemCacheEntry(value, _timestamp, timeout)));
61  _entries_by_timestamp.insert(std::make_pair(_timestamp, key));
62  }
63  else
64  _entries_by_key.insert(std::make_pair(key, MemCacheEntry(value)));
65 
66  return true;
67 }
68 
69 template <typename TKey, typename TValue>
70 inline bool MemCache<TKey, TValue>::find(const TKey& key)
71 {
72  std::shared_lock<std::shared_mutex> locker(_lock);
73 
74  // Try to find the given key
75  auto it = _entries_by_key.find(key);
76  if (it == _entries_by_key.end())
77  return false;
78 
79  return true;
80 }
81 
82 template <typename TKey, typename TValue>
83 inline bool MemCache<TKey, TValue>::find(const TKey& key, TValue& value)
84 {
85  std::shared_lock<std::shared_mutex> locker(_lock);
86 
87  // Try to find the given key
88  auto it = _entries_by_key.find(key);
89  if (it == _entries_by_key.end())
90  return false;
91 
92  value = it->second.value;
93  return true;
94 }
95 
96 template <typename TKey, typename TValue>
97 inline bool MemCache<TKey, TValue>::find(const TKey& key, TValue& value, Timestamp& timeout)
98 {
99  std::shared_lock<std::shared_mutex> locker(_lock);
100 
101  // Try to find the given key
102  auto it = _entries_by_key.find(key);
103  if (it == _entries_by_key.end())
104  return false;
105 
106  value = it->second.value;
107  timeout = it->second.timestamp + it->second.timespan;
108  return true;
109 }
110 
111 template <typename TKey, typename TValue>
112 inline bool MemCache<TKey, TValue>::remove(const TKey& key)
113 {
114  std::unique_lock<std::shared_mutex> locker(_lock);
115 
116  return remove_internal(key);
117 }
118 
119 template <typename TKey, typename TValue>
120 inline bool MemCache<TKey, TValue>::remove_internal(const TKey& key)
121 {
122  // Try to find the given key
123  auto it = _entries_by_key.find(key);
124  if (it == _entries_by_key.end())
125  return false;
126 
127  // Try to erase cache entry by timestamp
128  if (it->second.timestamp.total() > 0)
129  _entries_by_timestamp.erase(it->second.timestamp);
130 
131  // Erase cache entry
132  _entries_by_key.erase(it);
133 
134  return true;
135 }
136 
137 template <typename TKey, typename TValue>
139 {
140  std::unique_lock<std::shared_mutex> locker(_lock);
141 
142  // Clear all cache entries
143  _entries_by_key.clear();
144  _entries_by_timestamp.clear();
145 }
146 
147 template <typename TKey, typename TValue>
149 {
150  std::unique_lock<std::shared_mutex> locker(_lock);
151 
152  // Watchdog for cache entries
153  auto it_entry_by_timestamp = _entries_by_timestamp.begin();
154  while (it_entry_by_timestamp != _entries_by_timestamp.end())
155  {
156  // Check for the cache entry timeout
157  auto it_entry_by_key = _entries_by_key.find(it_entry_by_timestamp->second);
158  if ((it_entry_by_key->second.timestamp + it_entry_by_key->second.timespan) <= utc)
159  {
160  // Erase the cache entry with timeout
161  _entries_by_key.erase(it_entry_by_key);
162  _entries_by_timestamp.erase(it_entry_by_timestamp);
163  it_entry_by_timestamp = _entries_by_timestamp.begin();
164  continue;
165  }
166  else
167  break;
168  }
169 }
170 
171 template <typename TKey, typename TValue>
172 inline void MemCache<TKey, TValue>::swap(MemCache& cache) noexcept
173 {
174  std::unique_lock<std::shared_mutex> locker1(_lock);
175  std::unique_lock<std::shared_mutex> locker2(cache._lock);
176 
177  using std::swap;
178  swap(_timestamp, cache._timestamp);
179  swap(_entries_by_key, cache._entries_by_key);
180  swap(_entries_by_timestamp, cache._entries_by_timestamp);
181 }
182 
183 template <typename TKey, typename TValue>
184 inline void swap(MemCache<TKey, TValue>& cache1, MemCache<TKey, TValue>& cache2) noexcept
185 {
186  cache1.swap(cache2);
187 }
188 
189 } // namespace CppCommon
Memory cache.
Definition: memcache.h:30
size_t size() const
Get the memory cache size.
Definition: memcache.inl:19
bool remove(const TKey &key)
Remove the cache value with the given key from the memory cache.
Definition: memcache.inl:112
bool emplace(TKey &&key, TValue &&value, const Timespan &timeout=Timespan(0))
Emplace a new cache value with the given timeout into the memory cache.
Definition: memcache.inl:26
void clear()
Clear the memory cache.
Definition: memcache.inl:138
void swap(MemCache &cache) noexcept
Swap two instances.
Definition: memcache.inl:172
bool empty() const
Is the memory cache empty?
Definition: memcache.inl:12
void watchdog(const UtcTimestamp &utc=UtcTimestamp())
Watchdog the memory cache.
Definition: memcache.inl:148
bool find(const TKey &key)
Try to find the cache value by the given key.
Definition: memcache.inl:70
bool insert(const TKey &key, const TValue &value, const Timespan &timeout=Timespan(0))
Insert a new cache value with the given timeout into the memory cache.
Definition: memcache.inl:48
int64_t total() const noexcept
Get total value of the current timespan (total nanoseconds)
Definition: timespan.h:151
UTC timestamp.
Definition: timestamp.h:248
C++ Common project definitions.
Definition: token_bucket.h:15
void swap(FileCache &cache1, FileCache &cache2) noexcept
Definition: filecache.inl:23
void swap(MemCache< TKey, TValue > &cache1, MemCache< TKey, TValue > &cache2) noexcept
Definition: memcache.inl:184