23 #ifndef common_cache_hpp
24 #define common_cache_hpp
34 using namespace std::chrono_literals;
60 template <
class Key,
class Value>
class Cache {
71 std::chrono::steady_clock::time_point
hit_time;
83 typedef std::multimap<std::chrono::steady_clock::time_point,Key>
LRUMap;
85 typedef typename LRUMap::iterator
ILRUMap;
87 typedef typename LRUMap::const_iterator
CILRUMap;
97 Cache(
size_t max_size, std::chrono::seconds life_time ) {
99 life_time_s_ = life_time;
119 bool get(
const Key& key, Value &value ) {
122 if ( i != cache_.end() ) {
124 if ( life_time_s_ > 0s && std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - i->second.load_time ) > life_time_s_ ) {
125 if ( load( key, i->second.value ) ) {
127 i->second.load_time = std::chrono::steady_clock::now();
130 value = i->second.value;
131 auto prev_hit_time = i->second.hit_time;
132 i->second.hit_time = std::chrono::steady_clock::now();
133 updateLRU( i, prev_hit_time );
137 if ( load( key, value ) ) {
138 std::pair<Key,CacheEntry> p = std::pair<Key,CacheEntry>( key, { std::chrono::steady_clock::now(), std::chrono::steady_clock::now(), value } );
139 std::pair<CICacheMap,bool> ret;
140 ret = cache_.insert( p );
142 if ( cache_.size() > max_size_ ) removeLRU();
173 ICacheMap cache_entry = cache_.find( key );
174 if ( cache_entry != cache_.end() ) {
175 auto ret = lrumap_.equal_range( cache_entry->second.hit_time );
176 ILRUMap lru_entry = lrumap_.end();
177 for (
ILRUMap j = ret.first; j != ret.second; ++j ) {
178 if ( key == j->second ) {
183 if ( lru_entry != lrumap_.end() ) {
184 lrumap_.erase(lru_entry);
186 cache_.erase(cache_entry);
210 virtual bool load(
const Key& key, Value &value ) = 0;
224 lrumap_.insert( std::pair<std::chrono::steady_clock::time_point,Key>( (*iter).second.hit_time, (*iter).first ) );
231 auto oldest = lrumap_.begin();
232 auto entry = cache_.find( oldest->second );
233 if ( entry != cache_.end() ) cache_.erase( entry );
234 lrumap_.erase( oldest );
243 auto ret = lrumap_.equal_range( prev_hit_time );
244 ILRUMap update = lrumap_.end();
245 for (
ILRUMap i = ret.first; i != ret.second; ++i ) {
246 if ( i->second == iter->first ) {
251 if ( update != lrumap_.end() ) {
252 lrumap_.erase( update );
270 std::chrono::seconds life_time_s_ = 300s;