手撸LFU缓存结构,哈希表+二维链表

什么是LFU?
当内存不足时,优先删除被操作次数最少的元素。

数据结构设计

哈希表 + 二维双向链表

二维链表维护不同访问次数和相同访问次数结点集合之间的关系。每一列的双向链表是所有出现操作次数相同的节点的集合,次数链表的头节点之间也相互连接的,同样构成双向链表。

二维链表的结构:
在这里插入图片描述

链表中Node结点的设计:

public static class Node {
   
            Integer key;
            Integer value;
            Integer times;//记录被操作的次数
            Node up;//记录上一个结点
            Node down;//记录下一个结点

            public Node(Integer key, Integer value, Integer times) {
   
                this.key = key;
                this.value = value;
                this.times = times;
            }
        }

每一列的双向链表单独维护,每列之间也使用双向指针进行连接:

/**
         * 相当于一个二维的双向链表,上下链表的是相同次数的结点,左右连接的是不同次数的结点
         */
        public static class NodeList{
   
            Node head;//当前列的第一个结点
            Node tail;//当前列的最后一个结点
            NodeList last;//左边的结点
            NodeList next;//右边的结点

            public NodeList(Node head) {
   
                this.head = head;
                this.tail = head;
            }
            //新增一个节点,放到NodeList的头部
            public void addFromHead(Node node){
   
                node.down = head;
                head.up = node;
                head = head.up;
            }
            public boolean isEmpty(){
    return head == null;}

            //删除指定的结点
            public void deleteNode(Node node){
   
                if (head == tail) {
   
                    head = null;
                    tail = null;
                }else{
   
                    if (head == node) {
   
                        head = node.down;
                        head.up = null;
                    }else if (tail == node) {
   
                        tail = node.up;
                        tail.down = null;
                    }else{
   
                        node.up.down = node.down;
                        node.down.up = node.up;
                    }
                }
                //释放该结点的所有引用
                node.up = null;
                node.down = null;
            }
        }

LRU设计思路

当元素被操作(添加、访问…)后,将对应的Node的times++,然后被操作的结点从原来的列中删除,移到现在times所在的列。这样缓存中操作次数最少的元素就总是在第一列的第一个Node,当面临内存淘汰时就优先从头开始删除。

完整代码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值