#ifndef LFU_CACHE_POLICY_HPP #define LFU_CACHE_POLICY_HPP #include #include #include #include #include "cache_policy.hpp" namespace caches { template class LFUCachePolicy : public ICachePolicy { public: using lfu_iterator = typename std::multimap::iterator; LFUCachePolicy() = default; ~LFUCachePolicy() override = default; void Insert(const Key& key) override { constexpr std::size_t INIT_VAL = 1; // all new value initialized with the frequency 1 lfu_storage[key] = frequency_storage.emplace_hint( frequency_storage.cbegin(), INIT_VAL, key); } void Touch(const Key& key) override { // get the previous frequency value of a key auto elem_for_update = lfu_storage[key]; auto updated_elem = std::make_pair( elem_for_update->first + 1, elem_for_update->second); // update the previous value frequency_storage.erase(elem_for_update); lfu_storage[key] = frequency_storage.emplace_hint( frequency_storage.cend(), std::move(updated_elem)); } void Erase(const Key& key) override { frequency_storage.erase(lfu_storage[key]); lfu_storage.erase(key); } const Key& ReplCandidate() const override { // at the beginning of the frequency_storage we have the // least frequency used value return frequency_storage.cbegin()->second; } // return a key of a displacement candidate void Clear() override { frequency_storage.clear(); lfu_storage.clear(); } private: std::multimap frequency_storage; std::unordered_map lfu_storage; }; } // namespace caches #endif // LFU_CACHE_POLICY_HPP