From 506741fbdfacfbf3010559280c2f00c3e580e1f4 Mon Sep 17 00:00:00 2001 From: antpy Date: Thu, 24 Aug 2017 01:20:03 -0700 Subject: [PATCH] Basic, mildly tested LRU cache. --- src/LRUCache.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/LRUCache.h diff --git a/src/LRUCache.h b/src/LRUCache.h new file mode 100644 index 0000000..f101b3b --- /dev/null +++ b/src/LRUCache.h @@ -0,0 +1,60 @@ +#pragma once +#ifndef CACHE_H +#define CACHE_H + +#include +#include +#include +#include + +template +class LRUCache { + using Key_list = std::list>; + Key_list key_values; + std::unordered_map positions; + size_t max_values; + + void remove_oldest() { + while (positions.size() >= max_values) { + positions.erase(key_values.back().first); + key_values.pop_back(); + } + } + +public: + LRUCache(const size_t max_values) : max_values(max_values) { + } + + template + void insert(const K& key, VV&& value) { + remove_oldest(); + key_values.emplace_front(key, value); + positions[key] = key_values.begin(); + } + + std::pair find(const K& key) { + auto p = positions.find(key); + if (p == positions.end()) + return {nullptr, false}; + auto iter = p->second; + auto& value = iter->second; + // If the iterator is not at the front of the list, move it there. + if (iter != key_values.begin()) { + key_values.splice( + key_values.begin(), + key_values, + iter, + std::next(iter)); + } + positions[key] = key_values.begin(); + return {&(iter->second), true}; + } + + void debug_cache() { + for (auto& p : key_values) { + std::cout << p.first << ":" << p.second << std::endl; + } + } +}; + +#endif