-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlrucache.cpp
67 lines (61 loc) · 1.75 KB
/
lrucache.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdio.h>
#include <stdlib.h>
#include "logging.h"
#include "lrucache.h"
LruCache lruCacheCreate(int maxSize) {
LruCache l;
l.sentinel = (DoublyLinkedList*)malloc(sizeof(DoublyLinkedList));
l.sentinel->next = l.sentinel;
l.sentinel->prev = l.sentinel;
l.curSize = 0;
l.maxSize = maxSize;
l.lookups = l.misses = l.evictions = 0;
return l;
}
void lruCachePut(LruCache *cache, u64 key, void *value) {
DoublyLinkedList *sent = cache->sentinel;
if (cache->curSize == cache->maxSize) {
// Delete the oldest entry
DoublyLinkedList *dead = sent->next;
free(cache->map[dead->key].data);
cache->map.erase(dead->key);
dead->prev->next = dead->next;
dead->next->prev = dead->prev;
free(dead);
cache->curSize--;
cache->evictions++;
}
DoublyLinkedList *l = (DoublyLinkedList*)malloc(sizeof(DoublyLinkedList));
l->key = key;
l->prev = sent->prev;
l->next = sent;
sent->prev->next = l;
sent->prev = l;
LruCacheElement elem;
elem.data = value;
elem.listPtr = l;
cache->map[key] = elem;
cache->curSize++;
}
void* lruCacheGet(LruCache *cache, u64 key) {
LruCacheElement elem = cache->map[key];
if (elem.data) {
// Delete the list pointer from its current position...
DoublyLinkedList *l = elem.listPtr, *sent = cache->sentinel;
l->prev->next = l->next;
l->next->prev = l->prev;
// ... and move it to the end of the list
l->prev = sent->prev;
l->next = sent;
sent->prev->next = l;
sent->prev = l;
} else {
cache->misses++;
}
cache->lookups++;
return elem.data;
}
void logCacheStats(int level, LruCache *cache, const char *msg) {
log(level, "%s cache stats: %llu lookups / %llu misses / %llu evictions",
msg, cache->lookups, cache->misses, cache->evictions);
}