设计题——LPU缓存机制
关键点:怎么确认最近最少使用。
关键词:hash
关键思路:访问之前先删除再添加,保证hash表元素是按照访问时间从旧到新的,这样在删除“最久未使用”元素时,只需要迭代hash表,然后删除第一个元素即可。
代码:
typedef struct { int key; int val; UT_hash_handle hh; } LRUCache;int g_Size; LRUCache *hashtable = NULL;
LRUCache* lRUCacheCreate(int capacity) { g_Size = capacity; return hashtable ; }
int lRUCacheGet(LRUCache* obj, int key) { LRUCache *cur_usr = NULL; HASH_FIND_INT(hashtable, &key, cur_usr); if (cur_usr != NULL) { // 找到了,get存在的key,则该key被使用了一次,因此需要先删后入,满足LRU HASH_DEL(hashtable, cur_usr); HASH_ADD_INT(hashtable, key, cur_usr); return cur_usr->val; } else { // 没有找到 return -1; } }
void lRUCachePut(LRUCache* obj, int key, int value) { LRUCache *cur_usr = NULL, *next_usr = NULL; HASH_FIND_INT(hashtable, &key, cur_usr); if (cur_usr != NULL) { // 找到了,get存在的key,则该key被使用了一次,因此需要先删后入,满足LRU HASH_DEL(hashtable, cur_usr); cur_usr->key = key; cur_usr->val = value; HASH_ADD_INT(hashtable, key, cur_usr); } else { // 没有找到,新插入 int cnt = HASH_COUNT(hashtable); if (cnt == g_Size) { // 达到容量上限,删除最久未使用的数据 // HASH_ITER是一个宏定义,程序执行时被替换为一个循环 HASH_ITER(hh, hashtable, cur_usr, next_usr) { HASH_DEL(hashtable, cur_usr); free(cur_usr); break; } } LRUCache *new_usr = (LRUCache *)malloc(sizeof(LRUCache)); new_usr->key = key; new_usr->val = value; HASH_ADD_INT(hashtable, key, new_usr); } return; }
void lRUCacheFree(LRUCache* obj) { LRUCache *cur_usr = NULL, *next_usr = NULL; HASH_ITER(hh, hashtable, cur_usr, next_usr) { HASH_DEL(hashtable, cur_usr); free(cur_usr); } }