diff options
author | est31 <MTest31@outlook.com> | 2015-07-11 02:24:00 +0200 |
---|---|---|
committer | est31 <MTest31@outlook.com> | 2015-07-27 06:42:56 +0200 |
commit | c30a2d68541b6ff451d92709478b4e37cac86447 (patch) | |
tree | 03b92452d7b63e0a81f7e636e38e3c40c2ba1128 /src/util/container.h | |
parent | 454a29037061ba62d89af41ecae23b4424f41ea5 (diff) | |
download | minetest-c30a2d68541b6ff451d92709478b4e37cac86447.tar.gz minetest-c30a2d68541b6ff451d92709478b4e37cac86447.tar.bz2 minetest-c30a2d68541b6ff451d92709478b4e37cac86447.zip |
Add AreaStore data structure
Diffstat (limited to 'src/util/container.h')
-rw-r--r-- | src/util/container.h | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/util/container.h b/src/util/container.h index 936c46d61..267d54c16 100644 --- a/src/util/container.h +++ b/src/util/container.h @@ -309,5 +309,74 @@ protected: JSemaphore m_size; }; +template<typename K, typename V> +class LRUCache +{ +public: + LRUCache(size_t limit, void (*cache_miss)(void *data, const K &key, V *dest), + void *data) + { + m_limit = limit; + m_cache_miss = cache_miss; + m_cache_miss_data = data; + } + + void setLimit(size_t limit) + { + m_limit = limit; + invalidate(); + } + + void invalidate() + { + m_map.clear(); + m_queue.clear(); + } + + const V *lookupCache(K key) + { + typename cache_type::iterator it = m_map.find(key); + V *ret; + if (it != m_map.end()) { + // found! + + cache_entry_t &entry = it->second; + + ret = &entry.second; + + // update the usage information + m_queue.erase(entry.first); + m_queue.push_front(key); + entry.first = m_queue.begin(); + } else { + // cache miss -- enter into cache + cache_entry_t &entry = + m_map[key]; + ret = &entry.second; + m_cache_miss(m_cache_miss_data, key, &entry.second); + + // delete old entries + if (m_queue.size() == m_limit) { + const K &id = m_queue.back(); + m_map.erase(id); + m_queue.pop_back(); + } + + m_queue.push_front(key); + entry.first = m_queue.begin(); + } + return ret; + } +private: + void (*m_cache_miss)(void *data, const K &key, V *dest); + void *m_cache_miss_data; + size_t m_limit; + typedef typename std::template pair<typename std::template list<K>::iterator, V> cache_entry_t; + typedef std::template map<K, cache_entry_t> cache_type; + cache_type m_map; + // we can't use std::deque here, because its iterators get invalidated + std::list<K> m_queue; +}; + #endif |