veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename > Struct Template Reference

time-based LFRU cache. More...

Detailed Description

template<typename Key, typename Value, size_t Size, size_t TimeWindow = 10 * 60, typename = typename std::enable_if<(Size <= 50)>::type>
struct altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename >

if all cache items are newer than TimeWindow min, evict less frequently used element. otherwise, evict oldest item, with lowest frequency.

has O(Size) complexity, thus works best for caches with small number of keys

Definition at line 29 of file small_lfru_cache.hpp.

#include <small_lfru_cache.hpp>

+ Collaboration diagram for altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename >:

Public Member Functions

std::shared_ptr< Value > getOrDefault (Key key, std::function< std::shared_ptr< Value >()> factory)
 
void clear ()
 
void insert (Key key, std::shared_ptr< Value > value)
 
bool get (const Key &key, std::shared_ptr< Value > &out)
 

Member Function Documentation

◆ clear()

template<typename Key , typename Value , size_t Size, size_t TimeWindow = 10 * 60, typename = typename std::enable_if<(Size <= 50)>::type>
void altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename >::clear ( )
inline

Definition at line 55 of file small_lfru_cache.hpp.

55 {
56 size_ = 0;
57 for (auto& i : container_) {
58 i.clear();
59 }
60 }

◆ get()

template<typename Key , typename Value , size_t Size, size_t TimeWindow = 10 * 60, typename = typename std::enable_if<(Size <= 50)>::type>
bool altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename >::get ( const Key &  key,
std::shared_ptr< Value > &  out 
)
inline

Definition at line 108 of file small_lfru_cache.hpp.

108 {
109 // search for key
110 auto begin = container_.begin();
111 auto end = container_.begin() + size_;
112 auto it = std::find_if(
113 begin, end, [&key](const Item& i) { return i.key == key; });
114 if (it == end) {
115 // key not found
116 return false;
117 }
118
119 it->frequency++;
120 it->lastAccessed = currentTimestamp4();
121
122 // return result
123 out = it->value;
124
125 return true;
126 }
uint32_t currentTimestamp4()
Get current time as 4 bytes. If mock time is set, returns mock time.

◆ getOrDefault()

template<typename Key , typename Value , size_t Size, size_t TimeWindow = 10 * 60, typename = typename std::enable_if<(Size <= 50)>::type>
std::shared_ptr< Value > altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename >::getOrDefault ( Key  key,
std::function< std::shared_ptr< Value >()>  factory 
)
inline

Definition at line 44 of file small_lfru_cache.hpp.

45 {
46 std::shared_ptr<Value> value;
47 if (!get(key, value)) {
48 value = factory();
49 insert(key, value);
50 }
51
52 return value;
53 }

◆ insert()

template<typename Key , typename Value , size_t Size, size_t TimeWindow = 10 * 60, typename = typename std::enable_if<(Size <= 50)>::type>
void altintegration::cache::SmallLFRUCache< Key, Value, Size, TimeWindow, typename >::insert ( Key  key,
std::shared_ptr< Value >  value 
)
inline

Definition at line 62 of file small_lfru_cache.hpp.

62 {
63 auto current = currentTimestamp4();
64
65 if (size_ < Size) {
66 // cache can accept new elements
67 auto& it = container_[size_++];
68 it.frequency = 0;
69 it.key = key;
70 it.value = std::move(value);
71 it.lastAccessed = current;
72 return;
73 }
74
75 // it's time to evict someone
76 auto begin = container_.begin();
77 auto end = container_.end();
78 // iterator to least frequency item
79 auto min = begin;
80 // iterator to least recently used item
81 auto leastRecent = begin;
82 for (auto it = begin; it != end; ++it) {
83 if (it->frequency < min->frequency) {
84 min = it;
85 }
86
87 if (it->lastAccessed < leastRecent->lastAccessed ||
88 (it->lastAccessed == leastRecent->lastAccessed &&
89 it->frequency < leastRecent->frequency)) {
90 leastRecent = it;
91 }
92 }
93
94 // by default, use LFU policy and evict element with min frequency
95 auto evict = min;
96 if (leastRecent->lastAccessed <= current - TimeWindow) {
97 // if least recently element is not used in TimeWindow sec, evict it
98 evict = leastRecent;
99 }
100
101 // do evict
102 evict->key = key;
103 evict->frequency = 0;
104 evict->value = std::move(value);
105 evict->lastAccessed = current;
106 }

The documentation for this struct was generated from the following file: