|
| Cache (size_t max_size, std::chrono::seconds life_time) |
| Construct a cache with at most max_size entries, and a maximum life_time of the cached entry. More...
|
|
void | clear () |
| Wipes all cached entries. More...
|
|
void | erase (const Key &key) |
| Erase the key from the cache. More...
|
|
bool | get (const Key &key, Value &value) |
| Get a copy of the Value idenified by Key. More...
|
|
size_t | getExpiries () const |
| Get the number of times a Key was present in the cache (a hit) but expired so implictly calling a load. More...
|
|
size_t | getHits () const |
| Get the number of cache hits, which may include hits on expired entries - which still cause a load() call. More...
|
|
size_t | getMisses () const |
| Get the number of cache loads - the number of times a Key was requested but not present in the cache. More...
|
|
void | setMaxLifeTime (const std::chrono::seconds &seconds) |
| Set the maximum life time, in seconds, of a cached entry. More...
|
|
void | setMaxSize (size_t max_size) |
| Set the maximum size / number of entries to cache. More...
|
|
template<class Key, class Value>
class dodo::common::Cache< Key, Value >
Simple thread-safe Cache template for arbitrary Key-Value pairs.
A Cache is applicable where the get( const Key& key, Value &value ) that finds the key in the cache, is much faster than the load( const Key& key, Value &value ). Each CacheEntry tracks the latest hit and load times. In case of pressure on the max_size, entries with the lowest hit_time are evicted to make room for the new load(). Additionally, if life_time is non-zero and the Value's load time is older then that, load() is invoked even if get() is a cache hit, updating both the load time and the hit time.
The Key class must have equality (==) and ordering (<) operators for the template instantiation to compile.
- Template Parameters
-
Key | The unique Key type to the cached entries. |
Value | the cached Value type. |
The number of 'loads' is getMisses() + getExpiries().
The time complexity of the get call is O(N log N) where N is the number of cache entries. The cache and lrumap are backed by std::map and std::multimap respectively.
Note that get() receives a copy of the Value in the Cache. If thread A receives Value v1, thread B may cause the Value to get reloaded if its life_time expired , and that Value v2 might differ from v1. So the Cache does not guarentee that two values retrurned by get on the same Key are equal no matter how close they are in wallclock time.
using namespace std;
public:
TestCache(
size_t max_size, std::chrono::seconds life_time ) :
Cache<int, std::string>(max_size,life_time) {}
protected:
virtual bool load(
const int &key, std::string &value ) {
std::stringstream ss;
ss << "retrieving value for key " << key;
value = ss.str();
return true;
}
};
int main() {
TestCache cache( 38, 40s );
for ( int i = 0; i < 200; i++ ) {
std::string value;
cache.get( rand() % 40, value );
std::this_thread::sleep_for (std::chrono::milliseconds(rand() % 1000));
std::cout << "." << std::flush;
}
std::cout << std::endl;
cout << "hit " << cache.getHits() << endl;
cout << "miss " << cache.getMisses() << endl;
cout << "expired " << cache.getExpiries() << endl;
return 0;
}
Definition at line 60 of file cache.hpp.