设计题——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);
    }
}
posted @ 2021-11-20 10:51  bwinLv  阅读(81)  评论(0编辑  收藏  举报