第五关|LRU的实现

1、LRU概述

LRU(最近最少使用):淘汰最长时间没有被使用的页面。是大部分操作系统为最大化页面命中率而广泛采用的一种页面置换算法。发生缺页中断时,选择未使用时间最长的页面置换出去。

2、实现LRU

LeetCode146
使用Hash+双链表:

  1. Hash:查询数据是否在链表,用来做到O(1)访问元素
  2. 双链表:保证顺序,head附近:最近使用的;tail附近:最久未使用的
  • get操作:

在这里插入图片描述

  • put操作:
    1. 容量不够,剔除最后,最前新加

在这里插入图片描述

                   2.key值有,于是替换其值,并移至最前

在这里插入图片描述

public class LRUCache {
    class LinkNode{
        int key;
        int val;
        LinkNode front;
        LinkNode next;
        public LinkNode(int key, int val){
            this.key = key;
            this.val = val;
        }
    }

    Map<Integer, LinkNode> map = new HashMap<>();
    int capacity;
    LinkNode head = new LinkNode(0,0);
    LinkNode tail = new LinkNode(0, 0);

    public LRUCache(int capacity){
        this.capacity = capacity;
        head.next = tail;
        tail.front = head;
    }

    public int get(int key){
        if(map.containsKey(key)){
            LinkNode node = map.get(key);
            moveNodeToTop(node);//别忘了,使用了要移动到头部
            return node.val;
        }else{
            return -1;
        }
    }

    public void put(int key, int value){
        //新的,加
        if(!map.containsKey(key)){
            if(map.size() == capacity) deleteLastNode();
            LinkNode newNode = new LinkNode(key, value);
            addToHead(newNode);
            map.put(key, newNode);//别忘了
            //本身就在头部添加的,不需要移动到头部
        }else{//旧的,改
            LinkNode node = map.get(key);
            node.val = value;
            moveNodeToTop(node);//更改了,移动到头部
        }
    }

    public void deleteLastNode(){
        LinkNode lastNode = tail.front;
        lastNode.front.next = tail;
        tail.front = lastNode.front;
        map.remove(lastNode.key);
    }

    //移动到头部,1.相邻两节点搭线 2.添加到头部
    public void moveNodeToTop(LinkNode node){
        node.front.next = node.next;
        node.next.front = node.front;

        addToHead(node);

    }

    //将节点添加到头部
    public void addToHead(LinkNode node){
        LinkNode temp = head.next;
        head.next = node;
        node.front = head;
        node.next = temp;
        temp.front = node;
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
头哥实践教学平台存储系统设计(HUST)第5要求我们设计一个直接相联缓存系统。 直接相联缓存是一种简单的缓存结构,每个主存块只能放置在缓存中的某个固定位置。比如,如果我们的缓存总共有16个位置,那么主存块A只能存放在位置0(或称为槽位0),主存块B只能存放在位置1,以此类推。当需要将主存中的一个块存入缓存时,根据其物理地址,会直接确定其在缓存中的位置。 直接相联缓存的设计需要注意以下几点: 1. 设置合适的缓存容量和块大小。缓存容量应根据需求和可用资源进行合理规划。块大小则需根据主存块的大小进行设置,既要保证缓存能够存放足够多的主存块,又要尽量减少缓存的空间浪费。 2. 注缓存的组织结构。每个位置都需要有一个标签来记录其对应的主存块的地址信息,以便进行比较和查找。此外,还需要有一个有效位来表示该位置是否已经被占用,以及其他控制位来实现一些策略和操作。 3. 设计合理的替换策略。直接相联缓存中,当需要存入的主存块需要的位置已经被占用时,需要根据一定的策略替换掉已存在的主存块。常见的替换策略有最近最少使用(LRU)和随机替换等。 4. 实现高效的访问控制。直接相联缓存中,由于每个位置只能存放一个主存块,所以不会存在冲突问题。然而,需要根据给定的主存块地址进行查找和读写操作,并保证缓存与主存之间的一致性。 通过以上的设计和实现,我们可以完成头哥实践教学平台存储系统设计第5的直接相联缓存系统。该系统可以提高访问速度,并减少对主存的访问次数,从而提升整体性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值