22#include <unordered_map>
29template <
typename K,
typename T>
56template <
typename K,
typename T>
60 typedef typename std::list<Node<K, T>>::iterator
CacheIter;
61#define DIRTY "_$dirty$"
67 , defaultValue(defaultValue)
70 throw std::logic_error(
"Cache capacity cannot less than 1.");
82 cacheList.splice(cacheList.begin(), cacheList, cacheMap[key]);
83 cacheMap[key] = cacheList.begin();
84 valueMap[cacheMap[key]->value] = cacheList.begin();
85 cacheMap[key]->count++;
86 return cacheMap[key]->value;
89 void set(K key, T value)
93 throw std::logic_error(
"Can not cache the same key twice.");
97 if (cacheList.size() >= capacity)
99 deleteCache(cacheList.size() - capacity);
105 cacheList.front().bytes = sizeOf(value);
106 totalBytes += cacheList.front().bytes;
110 cacheMap[key] = cacheList.begin();
111 valueMap[cacheMap[key]->value] = cacheList.begin();
123 if (sizeOf && !this->sizeOf)
124 for (
auto& i : cacheList)
126 i.bytes = sizeOf(i.value);
127 totalBytes += i.bytes;
129 this->budget = bytes;
130 this->sizeOf = sizeOf;
135 size_t getSize()
const {
return cacheList.size(); }
142 if (!isExisted(value))
148 if (valueMap[value]->count > 0)
149 valueMap[value]->count--;
151 if (valueMap[value]->count == 0)
160 if (!isExisted(old_val))
164 valueMap[old_val]->value = new_val;
165 valueMap[new_val] = valueMap[old_val];
166 valueMap.erase(old_val);
169 auto& node = *valueMap[new_val];
170 totalBytes -= node.bytes;
171 node.bytes = sizeOf(new_val);
172 totalBytes += node.bytes;
179 throw std::logic_error(
"Cache capacity cannot less than 1.");
183 if (cacheList.size() > capacity)
185 deleteCache(cacheList.size() - capacity);
195 if (!isExisted(value))
200 auto item = valueMap[value];
205 cacheMap.erase(item->key);
212 for (
auto& i : cacheList)
216 cacheMap.erase(i.key);
229 for (
auto i = cacheList.begin(); i != cacheList.end();)
233 nvgDeleteImage(vg, i->value);
234 cacheMap.erase(i->key);
235 valueMap.erase(i->value);
236 totalBytes -= i->bytes;
237 i = cacheList.erase(i);
250 printf(
"===== cache size: %zu =====\n", cacheList.size());
251 for (
auto& i : cacheList)
253 printf(
"count: %zu, dirty: %d, value: %zu, key: %s\n", i.count,
254 i.dirty, i.value, i.key.c_str());
261 size_t totalBytes = 0;
262 std::function<size_t(T)> sizeOf;
269 if (budget == 0 || totalBytes <= budget || cacheList.size() < 2)
272 auto i = cacheList.end();
273 while (totalBytes > budget && i != std::next(cacheList.begin()))
278 nvgDeleteImage(vg, i->value);
279 cacheMap.erase(i->key);
280 valueMap.erase(i->value);
281 totalBytes -= i->bytes;
282 i = cacheList.erase(i);
286 std::list<Node<K, T>> cacheList;
287 std::unordered_map<K, CacheIter> cacheMap;
288 std::unordered_map<T, CacheIter> valueMap;
296 size_t deleteCache(
size_t num)
305 auto i = cacheList.end();
306 while (num > 0 && i != cacheList.begin())
312 nvgDeleteImage(vg, i->value);
313 cacheMap.erase(i->key);
314 valueMap.erase(i->value);
315 totalBytes -= i->bytes;
316 i = cacheList.erase(i);
322 bool isExisted(K key) {
return cacheMap.find(key) != cacheMap.end(); }
324 bool isExisted(T val) {
return valueMap.find(val) != valueMap.end(); }
326 bool isCacheHit(K key)
329 return !cacheMap[
key]->dirty;
352 void addCache(
const std::string& key,
size_t texture)
382 if (old_tex <= 0 || new_tex <= 0)
398 return (
size_t)w * (size_t)h * 4; });
409 nvgDeleteImage(vg, i.value);
#define DIRTY
Definition cache_helper.hpp:61
static VoidEvent * getWindowSizeChangedEvent()
Fired when the window's size changed.
static NVGcontext * getNVGContext()
The nanovg context every view draws with.
static VoidEvent * getExitEvent()
Fired when the app starts to exit, before the activities are deleted.
Subscription subscribe(Callback cb)
Definition event.hpp:81
Definition cache_helper.hpp:58
T get(K key)
Definition cache_helper.hpp:73
std::list< Node< K, T > > & getCacheList()
Definition cache_helper.hpp:246
void update(T old_val, T new_val)
Definition cache_helper.hpp:158
size_t getSize() const
Definition cache_helper.hpp:135
void markDirty(T value)
Definition cache_helper.hpp:193
void debug()
Definition cache_helper.hpp:248
void setMemoryBudget(size_t bytes, std::function< size_t(T)> sizeOf)
Definition cache_helper.hpp:121
static bool ALWAYS_CACHE_LOCAL_FILE
Definition cache_helper.hpp:63
void remove(T value)
Definition cache_helper.hpp:140
LRUCache(size_t c, T defaultValue)
Definition cache_helper.hpp:65
size_t getTotalBytes() const
Definition cache_helper.hpp:134
std::list< Node< K, T > >::iterator CacheIter
Definition cache_helper.hpp:60
void trimUnused()
Definition cache_helper.hpp:226
void setCapacity(int c)
Definition cache_helper.hpp:176
void markAllDirty()
Definition cache_helper.hpp:210
static size_t DEFAULT_CAPACITY
Definition cache_helper.hpp:62
void set(K key, T value)
Definition cache_helper.hpp:89
Definition singleton.hpp:24
Definition cache_helper.hpp:335
size_t getSize() const
Definition cache_helper.hpp:402
size_t getTotalBytes() const
Definition cache_helper.hpp:401
TextureCache()
Definition cache_helper.hpp:337
int getCache(const std::string &key)
Definition cache_helper.hpp:347
LRUCache< std::string, size_t > cache
Definition cache_helper.hpp:421
void updateCache(size_t old_tex, size_t new_tex)
Definition cache_helper.hpp:380
void trimUnused()
Definition cache_helper.hpp:417
void removeCache(size_t texture)
Definition cache_helper.hpp:363
void debug()
Definition cache_helper.hpp:419
void addCache(const std::string &key, size_t texture)
Definition cache_helper.hpp:352
void setMemoryBudget(size_t bytes)
Definition cache_helper.hpp:392
void clean()
Definition cache_helper.hpp:404
void markDirty(size_t texture)
Definition cache_helper.hpp:370
Definition actions.hpp:25
aurore::Box * key(const char *letter, float size=24)
Definition cache_helper.hpp:31
size_t count
Reference count, 1 for each cache hit.
Definition cache_helper.hpp:39
bool dirty
Cache entries marked as dirty will be refreshed when fetching the cache next time.
Definition cache_helper.hpp:36
T value
Definition cache_helper.hpp:33
size_t bytes
What the entry weighs (bytes), for a budget in bytes.
Definition cache_helper.hpp:42
K key
Definition cache_helper.hpp:32
Node(K k, T v)
Definition cache_helper.hpp:44