CacheLRU

CacheLRU contains maximum size items Eviction policy: 1. evict TTL-ed entry (if TTL enabled), otherwise 2. if oldest entry not expired - evict oldest accessed (LRU)

User can be informed about evicted entries via cache event list.

More...

Members

Functions

cacheEvents
auto cacheEvents()
clear
void clear()
enableCacheEvents
auto enableCacheEvents()
get
Nullable!V get(K k)
put
PutResult put(K k, V v, TTL ttl = TTL())
remove
bool remove(K k)
size
size_t size()
ttl
uint ttl()

Detailed Description

Implemented as HashMap and multi-dlist.

HashMap keeps

  1. cached value.
  2. pointer to dlist element.
  3. creation time (to check expiration and purge expired entry on get() without access to dlist).

dlist keep key, creation timestamp (to check expiration)

  1. key, so that we can remove entries from hashmap for lists heads (AccessIndex and TimeIndex)
  2. creation time, so that we can check expiration for 'TimeIndex'

Each element in dlist have two sets of double-links - first set create order by access time, second set for creation time.

Examples

1 import core.thread;
2 
3 // very basic example
4 auto lru = new CacheLRU!(int, string);
5 
6 lru.size(4).ttl(1);
7 assert(lru.size == 4);
8 assert(lru.ttl == 1);
9 
10 assert(lru.length == 0);
11 lru.put(1, "one");
12 lru.put(2, "two");
13 lru.put(3, "three");
14 lru.put(4, "four");
15 
16 auto v = lru.get(2);
17 assert(v=="two");
18 v = lru.get(4);
19 assert(v=="four");
20 
21 assert(lru.length == 4);
22 // As we reached cache capacity, next `put` must evict oldest never accessed key '1'
23 lru.put(5, "five");
24 assert(lru.length == 4);    // length did not changed
25 assert(lru.get(1).isNull);  // really evicted
26 
27 Thread.sleep(2.seconds);
28 v = lru.get(2); // it must be expired by ttl
29 assert(v.isNull);
30 assert(lru.length == 3);
31 v = lru.get(3); // it must be expired by ttl too
32 assert(v.isNull);
33 assert(lru.length == 2);
1 auto lru = new CacheLRU!(int, string);
2 () @nogc @safe nothrow {
3     lru.enableCacheEvents();
4     lru.put(1, "one");
5     assert(lru.get(1) == "one");
6     lru.put(1, "next one");
7     assert(lru.get(1) == "next one");
8     auto events = lru.cacheEvents();
9     assert(events.length == 1); // replaced old value
10     lru.put(2, "two");
11     lru.clear();
12     events = lru.cacheEvents();
13     assert(events.length == 2); // removed keys 1 and 2 during clear()
14 }();

Meta