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++
77 lines
1.7 KiB
C++
8 years ago
|
#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
|