libosmscout  1.1.1
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 <osmscout/CoreFeatures.h>
24 
25 #include <limits>
26 #include <list>
27 #include <unordered_map>
28 #include <vector>
29 
30 #include <osmscout/system/Assert.h>
31 
32 #include <osmscout/OSMScoutTypes.h>
33 
34 #include <osmscout/util/Logger.h>
35 
36 namespace osmscout {
37 
57  template <class K, class V, class IK = PageId>
58  class Cache
59  {
60  public:
64  struct CacheEntry
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),
78  value(value)
79  {
80  // no code
81  }
82  };
83 
89  class ValueSizer
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
K key
Definition: Cache.h:66
OSMSCOUT_API Log log
Definition: Cache.h:58
std::unordered_map< FileOffset, typename OrderList::iterator > Map
Definition: Cache.h:99
bool GetEntry(const K &key, CacheRef &reference)
Definition: Cache.h:165
size_t GetMaxSize() const
Definition: Cache.h:256
void DumpStatistics(const char *cacheName, const ValueSizer &sizer)
Definition: Cache.h:302
Definition: Cache.h:89
Cache(size_t maxSize)
Definition: Cache.h:140
Definition: Area.h:38
V value
Definition: Cache.h:67
size_t GetSize() const
Definition: Cache.h:275
void Flush()
Definition: Cache.h:264
Log & Debug(bool state)
Definition: Logger.h:428
CacheEntry(const K &key)
Definition: Cache.h:69
CacheEntry(const K &key, const V &value)
Definition: Cache.h:75
std::list< CacheEntry > OrderList
Definition: Cache.h:97
virtual size_t GetSize(const V &value) const =0
bool IsActive() const
Definition: Cache.h:150
size_t GetMemory(const ValueSizer &sizer) const
Definition: Cache.h:280
Cache::CacheRef SetEntry(const CacheEntry &entry)
Definition: Cache.h:204
typename OrderList::iterator CacheRef
Definition: Cache.h:98
void SetMaxSize(size_t maxSize)
Definition: Cache.h:244
virtual ~ValueSizer()=default
Definition: Cache.h:64