C ++ implémente le mécanisme d'élimination du cache LRU

Introduction à la mise en cache

Afin d'accélérer l'accès des utilisateurs, nous devons comprendre l'algorithme de mise en cache. Les algorithmes de mise en cache courants sont:

  • LRU: (utilisé le moins récemment): il est rarement utilisé récemment et ne sera pas éliminé en premier.
  • LFU (le moins fréquemment utilisé): Le moins fréquemment utilisé, le moins fréquemment utilisé sera éliminé en premier.
  • FIFO (premier entré, premier sorti): premier entré, premier sorti, le premier dans la mémoire tampon est éliminé en premier.
    Aujourd'hui, j'ai principalement appris l'algorithme LRU.

Introduction à LRU

LRU signifie que lorsque le cache est plein, si un nouveau programme est ajouté, celui qui n'a pas été consulté depuis le plus longtemps dans le cache est effacé du cache, puis le nouveau programme est ajouté à la première place dans le cache Ce programme est maintenant C'est le programme le plus fréquemment utilisé.

Donnez un exemple plus courant. Nous ouvrons d'abord WeChat, qui fonctionne maintenant en arrière-plan, puis ouvrons QQ et Weibo.
A ce moment, l'ordre des logiciels affichés en arrière-plan est: 1, Weibo 2, QQ 3, WeChat.
En supposant que ce téléphone mobile ne peut exécuter que 3 programmes en arrière-plan, lorsque nous activons NetEase Cloud Music, l'arrière-plan ferme automatiquement WeChat et place NetEase Cloud en premier.
L'ordre du logiciel d'arrière-plan à ce moment est: 1, NetEase Cloud 2, QQ 3, WeChat.

Principe de réalisation

Analyse des besoins:
1. La structure de données à implémenter est ordonnée ==> liste chaînée
2. Une recherche rapide est requise ==> table de hachage

Il est donc nécessaire de combiner les avantages de ces deux et d'utiliser les deux structures ensemble.
La structure de la conception est la suivante:

/*
 *双链表结点
 */ 
struct node{
    
    
    int val,key;
    node *prev,*next;
    node():prev(NULL),next(NULL){
    
    }
    node(int k,int v):key(k),val(v),prev(NULL),next(NULL){
    
    }
    
    //重载 == 号
    bool operator == (const node &p) const{
    
    
        return val==p.val&&key==p.key;
    }
 };

/*
 *双链表
 */ 
 class DoubleList{
    
    
     
     public:
        node *first;
        node *end;
        int n;

        DoubleList();
        void addFirst(node*);//在第一个位置插入新元素
        void remove(node*);//移除一个一定存在的节点
        int removeLast();//移除最后一个节点
        int size();
 };

La structure ci-dessus consiste à compléter une liste à double chaînage. La structure de la liste à double liaison est très efficace lors de l'insertion et de la suppression.
Ensuite, afin d'améliorer l'efficacité de la requête, le modèle STL unordered_map est utilisé ici. Cela équivaut à une carte non ordonnée, mais l'efficacité de la requête est stable et supérieure à celle d'une carte. Pour plus de détails, veuillez consulter: STL: unordered_map

La structure de cache construite est la suivante:

class LRUCache{
    
    
    private:
        unordered_map<int,node> map;
        DoubleList *lru;    
        int maxSize;

    public:
        LRUCache(){
    
    };
        LRUCache(int ms);
        int get(int key);
        void put(int key,int val);
        void show();
 };

Code complet

/*************************************************************************
	> File Name: lru.cpp
	> Author:Ryan 
	> Mail: 
	> Created Time: Tue Oct 13 20:31:11 2020
    > Function :实现LRU缓存淘汰策略
 ************************************************************************/

#include<iostream>
#include<unordered_map>
using namespace std;

/*
 *双链表结点
 */ 
struct node{
    
    
    int val,key;
    node *prev,*next;
    node():prev(NULL),next(NULL){
    
    }
    node(int k,int v):key(k),val(v),prev(NULL),next(NULL){
    
    }
    
    //重载 == 号
    bool operator == (const node &p) const{
    
    
        return val==p.val&&key==p.key;
    }
 };

/*
 *双链表
 */ 
 class DoubleList{
    
    
     
     public:
        node *first;
        node *end;
        int n;

        DoubleList();
        void addFirst(node*);
        void remove(node*);
        int removeLast();
        int size();
 };
/*
 *构造函数,新建首尾节点,相连
 */ 
DoubleList::DoubleList(){
    
    
    n=0;
    first = new node();
    end = new node();
    first->next = end;
    end->prev = first;
}

/*
 *在第一位添加一个节点
 */ 
void DoubleList::addFirst(node *nd){
    
    
    n++;
    //node *tmp = new node(nd->key,nd>val);
    node *t = first->next;
    nd->next = t;
    first->next = nd;
    nd->prev = first;
    t->prev = nd;
}

/*
 *删除一个肯定存在的节点
 */
void DoubleList::remove(node *nd){
    
    
    n--;

    node *p = first;
    while(p->key!=nd->key){
    
    
        p=p->next;
    }
    node *pt = p->prev;
    node *nt = p->next;
    pt->next = nt;
    nt->prev = pt;
    delete p;
}
/*
 *删除最后一个节点
 */ 
int DoubleList::removeLast(){
    
    
    if(n>=1){
    
    
        node *tmp = end->prev;
        node *pt = tmp->prev;
    
        pt->next = end;
        end->prev = pt;

        int t = tmp->key;
        delete tmp;
        n--;
        return t;
    }
    return -1;
}

int DoubleList::size(){
    
    
    return n;
}

class LRUCache{
    
    
    private:
        unordered_map<int,node> map;
        DoubleList *lru;    
        int maxSize;

    public:
        LRUCache(){
    
    };
        LRUCache(int ms);
        int get(int key);
        void put(int key,int val);
        void show();
 };

LRUCache::LRUCache(int ms){
    
    
    maxSize = ms;
    lru = new DoubleList();
}
/*
 *查找该节点
 */
int LRUCache::get(int key){
    
    
    if(map.count(key)==0){
    
    
        return -1;
    }
    else{
    
    
        int val = map.find(key)->second.val;
        put(key,val);
        return val;
    }
}
/*
*将节点提前
*/
void LRUCache::put(int key,int value){
    
    
    node *nd = new node(key,value);
    
    if(map.count(nd->key)==1){
    
    
        //移到前面
        lru->remove(nd);
        lru->addFirst(nd);
    }
    else{
    
    
        if(lru->n==maxSize){
    
    
            int k = lru->removeLast();
            map.erase(k);
            lru->addFirst(nd);
        }
        else{
    
    
            lru->addFirst(nd);
        }
    }
    map[key] = *nd;
}

void LRUCache::show(){
    
    
    if(lru->n==0) cout<<"empty task"<<endl;
    else{
    
    
        node *p = lru->first->next;
        cout<<"当前一共有"<<lru->n<<"个任务: "<<endl;
        for(int i=0;i<lru->n;i++){
    
    
            cout<<"第"<<i+1<<"个任务: "<<p->val<<endl;
            p=p->next;
        }
    }
}

int main(){
    
    
    LRUCache *l = new LRUCache(3);
    l->put(1,2);
    l->put(2,3);
    l->put(3,4);
    l->put(4,5);
    l->show();
}

Utilisez list + unordered_map pour voir ce grand dieu: cache LRU

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45146520/article/details/109078174
conseillé
Classement