类似LRU定时清除缓存的缓存优化算法详解(缓存淘汰策略)

缓存淘汰过程

  设计一个类似于LFU 和LRU 的缓存 优化 算法  可以变更的缓存结构

public class Cache {

    //首先自己定义缓存优化算法的基本的数据结构以及操作缓存的方法
    //设计具有双指针的结点
    public class Node<V>{
        public V value;
        public Node<V>last;
        public Node<V>next;
        public Node(V value){
            this.value=value;

        }
    }
    //设计的双端队列结构
    public class NodeDoubleLinKList<V>{
        private Node<V>head;
        private Node<V>tail;
        public NodeDoubleLinKList(){
            this.head=head;
            this.tail=tail;
        }
        //添加结点到尾部的逻辑逻辑
        public void addNode(Node<V>newNode){
            if(newNode==null){
                return;
            }
            //说明双端链表中只有一个结点  ,那么让头结点的指针和尾结点指针指向该结点即可
            if(head==newNode){
                this.head=newNode;
                this.tail=newNode;
            }else {
                newNode.last=this.tail;
                this.tail.next=newNode;
                this.tail=newNode;
            }
        }
        //移动结点到尾部的逻辑
        public void moveNodeToTail(Node<V>node){
            //如果当前结点就是尾结点,直接返回
            if(this.tail==node){
                return;
            }
            if(this.head==node){
                //head指针重定向
                this.head=node.next;
                this.head.last=null;
            }else{
                //解放指向node的指针
                node.last.next=node.next;
                node.next.last=node.last;
            }
            //node指针重定向
            node.last=this.tail;
            node.next=null;
            this.tail.next=node;
            this.tail=node;

        }

        //移除头结点的逻辑
        public Node<V>removeHead(){
            if(head==null){
                return null;
            }
            Node<V>res=head;
            //如果双端链表中只有一个结点
            if(this.head==this.tail){
                this.tail=null;
                this.head=null;
            }else {
                //head的指针指向重定向
                this.head=res.next;
                res.next=null;
                this.head.last=null;
            }
            return res;
        }
    }

    //缓存优化算法的具体实现逻辑
    //把记录之间按照访问的频率进行划分
    //就是上面自己定义的NodeDoubleLinkList
    //一旦加入新的记录,就把该纪录加到NodeDoubleLinkedList的尾部(addNdoe)
    //一旦获得(get)或者设置(set)一个key,就将这个key对应的node在NodeDoubleLinkList中调整到尾部(moveNodToTail),一旦cache满了就删除最不经常使用的记录(removeHead)
    //为了能够让每一个key都能在双端链表中找到对应的结点
    public class MyCache<K,V>{
        private HashMap<K, Node<V>>keyNodeMap;
        private HashMap<Node<V>,K>nodeKeyMap;
        private NodeDoubleLinKList<V>nodeList;
        private int capacity;
        public MyCache(int capacity){
            if(capacity<1){![在这里插入图片描述](https://img-blog.csdnimg.cn/20190421000529862.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjQyNDAyNA==,size_16,color_FFFFFF,t_70)
                throw new RuntimeException("should be more than 0");
            }
            this.keyNodeMap=new HashMap<K, Node<V>>();
            this.nodeKeyMap=new HashMap<Node<V>, K>();
            this.nodeList=new NodeDoubleLinKList();
            this.capacity=capacity;
        }
        public V get(K key){
            if(this.keyNodeMap.containsKey(key)){
                Node<V>resNode=this.keyNodeMap.get(key);
                this.nodeList.moveNodeToTail(resNode);
                return resNode.value;
            }
            return null;
        }
        public  void set (K key,V value){
            if(this.keyNodeMap.containsKey(key)){
                Node<V>node=this.keyNodeMap.get(key);
                node.value=value;
                this.nodeList.moveNodeToTail(node);
            }else{
                Node<V>newNode=new Node<V>(value);
                this.keyNodeMap.put(key, newNode);
                this.nodeKeyMap.put(newNode,key );
                this.nodeList.addNode(newNode);
                if(this.keyNodeMap.size()==this.capacity+1){
                    this.removeMostUnusedCache();
                }
            }
        }
        //清理缓存空间
        private  void removeMostUnusedCache() {
            Node<V>removeNode=this.nodeList.removeHead();
            K  removeKey=this.nodeKeyMap.get(removeNode);
            this.nodeKeyMap.remove(removeNode);
            this.keyNodeMap.remove(removeKey);

        }
        //这里执行缓存缓存    如果在web环境下也可以  在web.xml中定义ServletContextListener 来监听执行你的定时任务

        //	如果你用spring,那么你不需要写Timer类了,在schedulingContext-timer.xml 中进行配置就可以了
        //org.springframework.scheduling.timer.ScheduledTimerTask
        public class ListByDayTimerTask extends TimerTask{

            @Override
            public void run() {
                removeMostUnusedCache();
            }
        }

        //定时清除缓存
        public void  Timingexecution(){
            Timer timer=new Timer();
            timer.schedule(new ListByDayTimerTask(),10000,86400000);
        }

    }

}

缓存优化淘汰过程图解

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值