LRU:least recently used

LRU:least recently used

  • 最近最少使用算法,即选择最近最久未使用的页面予以淘汰

实现:

  • 使用hash_map+双向链表,实现复杂度O(1)

应用场景:

  • 底层的内存管理,页面置换算法
  • 一般的缓存服务,memcache/redis等
  • 部分业务场景

缺点:

  • 向前看,但过去与未来之间并无必然的联系
  • 偶然性、周期性的批量操作会导致命中率急剧下降,缓存污染的情况比较严重

代码示例:

#include <unordered_map>

template <typename TypeK, typename TypeV>
struct CacheNode{
    TypeK key;
    TypeV value;
    CacheNode *pre, *next;
    CacheNode(TypeK k, TypeV v) : key(k),value(v),pre(NULL),next(NULL){};
};

template <typename TypeK, typename TypeV>
class LruCache{
public:
    LruCache(int capacity = 100):size(capacity),head(NULL),tail(NULL){}
    TypeV *get(TypeK key){
       typename LRU_MAP::iterator it = mapCache.find(key);
        if (it == mapCache.end()){
            return NULL;
        } else {
            TemplateNode *node = it->second;
            remove(node);
            setHead(node);
            return &node->value;
        }
    }
    void set(TypeK key, TypeV value){
        typename LRU_MAP::iterator it = mapCache.find(key);
        if (it != mapCache.end()){
            TemplateNode *node = it->second;
            remove(node);
            setHead(node);
        } else {
            if (mapCache.size()>=size){
                typename LRU_MAP::iterator it_tail = mapCache.find(tail->key);
                TemplateNode *old = tail;
                remove(tail);
                mapCache.erase(it_tail);
                delete old;
            }
            TemplateNode *newNode = new TemplateNode(key, value);
            setHead(newNode);
            mapCache[key] = newNode;
        }
    }
private:
    int size;
    typedef CacheNode<TypeK, TypeV> TemplateNode;
    typedef unordered_map<TypeK, TemplateNode*> LRU_MAP;
    
    TemplateNode *head, *tail;
    LRU_MAP mapCache;
private:
    void remove(TemplateNode *node){
        if (node->pre){
            node->pre->next = node->next;
        } else {
            head = node->next;
        }
        if (node->next){
            node->next->pre = node->pre;
        } else {
            tail = node->pre;
        }
    }
    void setHead(TemplateNode *node){
        node->next = head;
        node->pre  = NULL;
        if (head){
            head->pre = node;
        }
        head = node;
        if (!tail){
            tail = head;
        }
    }
};
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。