You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.7 KiB
C++

#ifndef LFU_CACHE_POLICY_HPP
#define LFU_CACHE_POLICY_HPP
#include <cstddef>
#include <unordered_map>
#include <map>
#include <iostream>
#include "cache_policy.hpp"
namespace caches
{
template <typename Key>
class LFUCachePolicy : public ICachePolicy<Key>
{
public:
using lfu_iterator = typename std::multimap<std::size_t, Key>::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<std::size_t, Key> frequency_storage;
std::unordered_map<Key, lfu_iterator> lfu_storage;
};
} // namespace caches
#endif // LFU_CACHE_POLICY_HPP