5#ifndef ASW_SRC_LRU_CACHE_H
6#define ASW_SRC_LRU_CACHE_H
11#include <unordered_map>
23template <
typename Key,
typename Value,
typename Hash,
typename Equal>
class LruCache {
32 template <
typename K> Value*
find(
const K& key)
34 auto it =
_map.find(key);
35 if (it ==
_map.end()) {
38 it->second.last_used = ++
_clock;
39 return &it->second.value;
50 =
_map.insert_or_assign(std::move(key),
Entry { std::move(value), 0 }).first->second;
51 entry.last_used = ++
_clock;
76 const std::size_t keep =
_map.size() / 2;
84 for (
const auto& [key, entry] :
_map) {
85 _stamps.push_back(entry.last_used);
90 const auto cutoff_it =
_stamps.begin() +
static_cast<std::ptrdiff_t
>(
_stamps.size() - keep);
92 const uint64_t cutoff = *cutoff_it;
93 std::erase_if(
_map, [cutoff](
const auto& item) {
return item.second.last_used < cutoff; });
96 std::unordered_map<Key, Entry, Hash, Equal>
_map;
105 seed ^= hash + 0x9e3779b9 + ((seed << 6) + (seed >> 2));
A hash map with a size limit. When full, the least recently used half is dropped, so entries in use e...
std::unordered_map< Key, Entry, Hash, Equal > _map
Value * find(const K &key)
Find an entry and mark it used.
std::vector< uint64_t > _stamps
Value & insert(Key key, Value value)
Add or replace an entry, dropping old entries first when full.
LruCache(std::size_t limit)
void hash_combine(std::size_t &seed, std::size_t hash)
Combine a hash into a seed, as boost::hash_combine does.