libosmscout 1.1.1
Loading...
Searching...
No Matches
Cache.h
Go to the documentation of this file.
1#ifndef OSMSCOUT_CACHE_H
2#define OSMSCOUT_CACHE_H
3
4/*
5 This source is part of the libosmscout library
6 Copyright (C) 2009 Tim Teulings
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <limits>
24#include <list>
25#include <unordered_map>
26#include <vector>
27
28#include <osmscout/lib/CoreFeatures.h>
29
31
33
34#include <osmscout/log/Logger.h>
35
36namespace osmscout {
37
57 template <class K, class V, class IK = PageId>
58 class Cache
59 {
60 public:
65 {
66 K key; // NOLINT
67 V value; // NOLINT
68
69 explicit CacheEntry(const K& key)
70 : key(key)
71 {
72 // no code
73 }
74
75 CacheEntry(const K& key,
76 const V& value)
77 : key(key),
79 {
80 // no code
81 }
82 };
83
90 {
91 public:
92 virtual ~ValueSizer() = default;
93
94 virtual size_t GetSize(const V& value) const = 0;
95 };
96
97 using OrderList = std::list<CacheEntry>;
98 using CacheRef = typename OrderList::iterator;
99 using Map = std::unordered_map<K, typename OrderList::iterator>;
100
101 private:
102 size_t size=0; //<! Current size fo the cache
103 size_t maxSize; //<! Maximum size of the cache
104 OrderList order; //<! Order list (by cache access) of cache entries for least recently used cache flush
105 Map map; //<! Key=>Value map
106 CacheRef previousEntry; //<! Reference to the last access cache entry
107
108 private:
109
110 IK KeyToInternalKey(K key)
111 {
112 return key - std::numeric_limits<K>::min();
113 }
114
119 void StripCache()
120 {
121 while (size>maxSize) {
122 // Remove oldest entry from cache...
123
124 // Get oldest entry an dremove it from the map
125 map.erase(map.find(order.back().key));
126
127 // Remove it from order list
128 order.pop_back();
129
130 previousEntry=order.end();
131
132 size--;
133 }
134 }
135
136 public:
140 explicit Cache(size_t maxSize)
141 : maxSize(maxSize)
142 {
143 map.reserve(maxSize);
144 previousEntry=order.end();
145 }
146
150 bool IsActive() const
151 {
152 return maxSize>0;
153 }
154
165 bool GetEntry(const K& key,
166 CacheRef& reference)
167 {
168 if (!IsActive()) {
169 return false;
170 }
171
172 // Cached cache access
173 if (previousEntry!=order.end() &&
174 previousEntry->key==key) {
175 reference=previousEntry;
176 return true;
177 }
178
179 typename Map::iterator iter=map.find(key);
180
181 if (iter!=map.end()) {
182 // Move key/value to the start of the order list
183 order.splice(order.begin(),order,iter->second);
184
185 // Update the map with the new iterator into the order list
186 iter->second=order.begin();
187
188 reference=order.begin();
189 previousEntry=reference;
190
191 return true;
192 }
193
194 return false;
195 }
196
204 typename Cache::CacheRef SetEntry(const CacheEntry& entry)
205 {
206 if (!IsActive()) {
207 order.clear();
208
209 order.push_front(entry);
210
211 previousEntry=order.begin();
212 return order.begin();
213 }
214
215 typename Map::iterator iter=map.find(entry.key);
216
217 if (iter!=map.end()) {
218 // Move key/value to the start of the order list
219 order.splice(order.begin(),order,iter->second);
220
221 // Update the map with the new iterator into the order list
222 iter->second=order.begin();
223
224 order.front().value=entry.value;
225 }
226 else {
227 // Place key/value to the start of the order list
228 order.push_front(entry);
229 size++;
230 // Update the map with the new iterator into the order list
231 map[entry.key]=order.begin();
232
233 StripCache();
234 }
235
236 previousEntry=order.begin();
237 return order.begin();
238 }
239
244 void SetMaxSize(size_t maxSize)
245 {
246 this->maxSize=maxSize;
247
248 StripCache();
249
250 map.reserve(maxSize);
251 }
252
256 size_t GetMaxSize() const
257 {
258 return maxSize;
259 }
260
264 void Flush()
265 {
266 order.clear();
267 map.clear();
268 size=0;
269 previousEntry=order.end();
270 }
271
275 size_t GetSize() const
276 {
277 return size;
278 }
279
280 size_t GetMemory(const ValueSizer& sizer) const
281 {
282 size_t memory=0;
283
284 // Size of map
285 memory+=map.size()*sizeof(CacheRef);
286
287 // Size of list
288 memory+=size*sizeof(CacheEntry);
289
290 for (typename std::list<CacheEntry>::const_iterator entry=order.begin();
291 entry!=order.end();
292 ++entry) {
293 memory+=sizer.GetSize(entry->value);
294 }
295
296 return memory;
297 }
298
302 void DumpStatistics(const char* cacheName, const ValueSizer& sizer)
303 {
304 log.Debug() << cacheName << " entries: " << size << ", memory " << GetMemory(sizer);
305 }
306 };
307}
308
309#endif
Definition Cache.h:90
virtual size_t GetSize(const V &value) const =0
virtual ~ValueSizer()=default
bool IsActive() const
Definition Cache.h:150
bool GetEntry(const K &key, CacheRef &reference)
Definition Cache.h:165
size_t GetSize() const
Definition Cache.h:275
std::list< CacheEntry > OrderList
Definition Cache.h:97
std::unordered_map< FileOffset, typename OrderList::iterator > Map
Definition Cache.h:99
Cache(size_t maxSize)
Definition Cache.h:140
Cache::CacheRef SetEntry(const CacheEntry &entry)
Definition Cache.h:204
void Flush()
Definition Cache.h:264
typename OrderList::iterator CacheRef
Definition Cache.h:98
size_t GetMaxSize() const
Definition Cache.h:256
void DumpStatistics(const char *cacheName, const ValueSizer &sizer)
Definition Cache.h:302
size_t GetMemory(const ValueSizer &sizer) const
Definition Cache.h:280
void SetMaxSize(size_t maxSize)
Definition Cache.h:244
OSMSCOUT_API Log log
Definition LoggerImpl.h:95
Definition Area.h:39
CacheEntry(const K &key, const V &value)
Definition Cache.h:75
CacheEntry(const K &key)
Definition Cache.h:69
K key
Definition Cache.h:66
V value
Definition Cache.h:67