1+ //
2+ // LRU Cache Plugin with Hooks for libCacheSim plugin_cache.c
3+ // This implements the hook-based plugin system that plugin_cache.c expects
4+ //
5+
6+ #include < glib.h>
7+ #include < libCacheSim.h>
8+ #include < stdbool.h>
9+ #include < stdint.h>
10+ #include < stdlib.h>
11+
12+ #include < unordered_map>
13+
14+ class StandaloneLRU {
15+ public:
16+ struct Node {
17+ obj_id_t obj_id;
18+ uint64_t obj_size;
19+ Node *prev;
20+ Node *next;
21+
22+ Node (obj_id_t k = 0 , uint64_t obj_size = 0 )
23+ : obj_id(k), obj_size(obj_size), prev(nullptr ), next(nullptr ) {}
24+ };
25+
26+ std::unordered_map<obj_id_t , Node *> cache_map;
27+ Node *head;
28+ Node *tail;
29+
30+ StandaloneLRU () {
31+ head = new Node ();
32+ tail = new Node ();
33+ head->next = tail;
34+ tail->prev = head;
35+ }
36+
37+ ~StandaloneLRU () {
38+ while (head) {
39+ Node *temp = head;
40+ head = head->next ;
41+ delete temp;
42+ }
43+ }
44+
45+ void add_to_head (Node *node) {
46+ node->prev = head;
47+ node->next = head->next ;
48+ head->next ->prev = node;
49+ head->next = node;
50+ }
51+
52+ void remove_node (Node *node) {
53+ node->prev ->next = node->next ;
54+ node->next ->prev = node->prev ;
55+ }
56+
57+ Node *remove_tail () {
58+ Node *last_node = tail->prev ;
59+ remove_node (last_node);
60+ return last_node;
61+ }
62+
63+ void move_to_head (Node *node) {
64+ remove_node (node);
65+ add_to_head (node);
66+ }
67+
68+ void cache_hit (obj_id_t obj_id) {
69+ Node *node = cache_map[obj_id];
70+ move_to_head (node);
71+ }
72+
73+ void cache_miss (obj_id_t obj_id, uint64_t obj_size) {
74+ Node *new_node = new Node (obj_id, obj_size);
75+ cache_map[obj_id] = new_node;
76+ add_to_head (new_node);
77+ }
78+
79+ obj_id_t cache_eviction () {
80+ Node *node = remove_tail ();
81+ obj_id_t evicted_id = node->obj_id ;
82+ cache_map.erase (evicted_id);
83+ delete node;
84+ return evicted_id;
85+ }
86+
87+ void cache_remove (obj_id_t obj_id) {
88+ auto it = cache_map.find (obj_id);
89+ if (it == cache_map.end ()) {
90+ return ;
91+ }
92+ Node *node = it->second ;
93+ remove_node (node);
94+ cache_map.erase (it);
95+ delete node;
96+ }
97+ };
98+
99+ // C interface for the plugin hooks
100+ extern " C" {
101+
102+ // implement the cache init hook
103+ void *cache_init_hook (const common_cache_params_t ccache_params) {
104+ // initialize the LRU cache
105+ StandaloneLRU *lru_cache = new StandaloneLRU ();
106+ return lru_cache;
107+ }
108+
109+ // implement the cache hit hook
110+ void cache_hit_hook (void *data, const request_t *req) {
111+ // move object to the head of the list
112+ StandaloneLRU *lru_cache = (StandaloneLRU *)data;
113+ lru_cache->cache_hit (req->obj_id );
114+ }
115+
116+ // implement the cache miss hook
117+ void cache_miss_hook (void *data, const request_t *req) {
118+ // insert object into the cache
119+ StandaloneLRU *lru_cache = (StandaloneLRU *)data;
120+ lru_cache->cache_miss (req->obj_id , req->obj_size );
121+ }
122+
123+ // implement the cache eviction hook
124+ obj_id_t cache_eviction_hook (void *data, const request_t *req) {
125+ // evict the least recently used object
126+ StandaloneLRU *lru_cache = (StandaloneLRU *)data;
127+ return lru_cache->cache_eviction ();
128+ }
129+
130+ // implement the cache remove hook
131+ void cache_remove_hook (void *data, const obj_id_t obj_id) {
132+ // remove object from the cache
133+ StandaloneLRU *lru_cache = (StandaloneLRU *)data;
134+ lru_cache->cache_remove (obj_id);
135+ }
136+
137+ } // extern "C"
0 commit comments