LRU算法

本文介绍了几种常见的缓存算法,包括FIFO、LFU、LRU及其变种,并通过生动的例子帮助理解每种算法的特点及应用场景。同时,还提供了一个LRU缓存实现的示例代码。
今天班车上读了池建强君的《每个人都该懂点缓存》,很佩服,能把艰涩的技术讲的如此生动,读起来还引人入胜,确实是一件非常厉害的事。作为一名程序员,我着重写一下文中提到的缓存的算法。

原文链接如下:http://www.bubuko.com/news/detail-29818.html(由于首发是微信公共账号,所以web上全是转载)

下面引用一段:

常用的一些算法包括:FIFO、LFU、LRU、LRU2、ARC 等。

  FIFO 就是先进先出,一种非常简单的算法,缓存数据达到上限的时候,最先进入缓存的数据会最先被踢出去。很多老员工看到这一条都义愤填膺,所以,这个算法注定是不被喜欢的,但是由于它简单直接,很多开发者喜欢。嗯,有些企业老板也比较喜欢。Second Chance 和 CLock 是基于 FIFO 的改进,算法更加先进合理,也更复杂,微信里写了也没人看,感兴趣的话,Google「缓存算法 CLock」等。

  LFU 的全称是 Least Frequently Used,最少使用算法,系统会为每个对象计算使用频率,最不常用的缓存对象会被踢走,简单粗暴。缺点是,一个传统工业时代曾经被重用过的老员工,在互联网时代没用了,由于其前期使用频率很高,吃老本,所以数据会一直保存在缓存系统中,反而是后起之秀,往往会遭遇到误杀的不公正待遇。差评。

  LRU 的全称是 Least Recently Used,也就是最近最少使用算法。基本思路是,如果一个数据最近一段时间被使用的频率很少,那将来被用到的可能性也会很低。看到这儿,那些近期没什么开发任务的童靴,你们要小心了。好评。

  LRU2 和 ARC 都是基于 LRU 的改进,有兴趣的可以上网查查。

  很多我们耳熟能详的缓存产品,比如 Memcached、Redis、Ehcache、OSCache 等,都参考了类似的算法,要么进行加强,要么进行简化,目标就是提升缓存的命中率,降低缓存成本。

Leetcode上有一道题是讲LRU Cache的

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

class LRUCache{
    struct NODE{
        int key;
        int val;
        NODE* pre;
        NODE* next;
        NODE(int key,int value):key(key),val(value),pre(NULL),next(NULL){}
        NODE():val(0),pre(NULL),next(NULL){}
    };
private:
     unordered_map<int,NODE*> m_mp;
     int m_cap;
     int m_size;
     NODE* m_pHead;
     NODE* m_pTail;

    void putToHead(NODE* pNode)
    {
        pNode->pre=m_pHead;
        pNode->next=m_pHead->next;
        m_pHead->next->pre=pNode;
        m_pHead->next=pNode;
    }
public:
    LRUCache(int capacity) {
        m_cap=capacity;
        m_size=0;
        m_mp.clear();
        m_pHead=new NODE;
        m_pTail=new NODE;
        m_pHead->next=m_pTail;
        m_pTail->pre=m_pHead;

    }
    ~LRUCache() {
        //m_cap=capacity;
        m_size=0;
        m_mp.clear();
        delete m_pHead;
        delete m_pTail;
    }
    int get(int key) {
        unordered_map<int,NODE*>::iterator iMp=m_mp.find(key);
        if(iMp==m_mp.end())
           return -1;
        else
        {
           NODE* pCur=iMp->second;
           NODE* pPre=pCur->pre;
           NODE* pNext=pCur->next;
           pPre->next=pNext;
           pNext->pre=pPre;
           putToHead(pCur);
           return pCur->val;
        }
    }

    void set(int key, int value) {
        unordered_map<int,NODE*>::iterator iMp=m_mp.find(key);
        if(iMp==m_mp.end())
        {
            NODE* p=new NODE(key,value);
            putToHead(p);
            m_mp[key]=p;
            m_size++;
        }
        else
        {
            NODE* p=iMp->second;
            p->val=value;
            NODE* pPre=p->pre;
            NODE* pNext=p->next;
            pPre->next=pNext;
            pNext->pre=pPre;
            putToHead(p);
        }
        if(m_size>m_cap)
        {
            NODE* pCur=m_pTail->pre;
            NODE* pPre=pCur->pre;
            pPre->next=m_pTail;
            m_pTail->pre=pPre;
            m_mp.erase(m_mp.find(pCur->key));
            delete pCur;
            m_size--;
        }
    }


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值