Implemented as HashMap and multi-dlist.
HashMap keeps
dlist keep key, creation timestamp (to check expiration)
Each element in dlist have two sets of double-links - first set create order by access time, second set for creation time.
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 }();
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.