#include #include #include #include #include #include template class LRUCache { public: LRUCache(size_t capacity) : capacity_(capacity) { assert(capacity > 0); } std::shared_ptr get(const Key& key) { auto it = cache_.find(key); if (it == cache_.end()) { std::shared_ptr ptr(new Value()); put(key, ptr); return ptr; } touch(it); return it->second.first; } private: void put(const Key& key, const std::shared_ptr& value) { auto it = cache_.find(key); if (it != cache_.end()) { touch(it); it->second.first = value; } else { if (cache_.size() == capacity_) { cache_.erase(usage_.back()); usage_.pop_back(); } usage_.push_front(key); cache_[key] = { value, usage_.begin() }; } } typedef typename std::list::iterator ListIt; std::unordered_map, ListIt>> cache_; std::list usage_; size_t capacity_; void touch(typename std::unordered_map, ListIt>>::iterator it) { usage_.erase(it->second.second); usage_.push_front(it->first); it->second.second = usage_.begin(); } }; #pragma once