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

类似LRU定时清除缓存的缓存优化算法详解(缓存淘汰策略)_第1张图片

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

public class Cache {

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

        }
    }
    //设计的双端队列结构
    public class NodeDoubleLinKList{
        private Nodehead;
        private Nodetail;
        public NodeDoubleLinKList(){
            this.head=head;
            this.tail=tail;
        }
        //添加结点到尾部的逻辑逻辑
        public void addNode(NodenewNode){
            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(Nodenode){
            //如果当前结点就是尾结点,直接返回
            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 NoderemoveHead(){
            if(head==null){
                return null;
            }
            Noderes=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{
        private HashMap>keyNodeMap;
        private HashMap,K>nodeKeyMap;
        private NodeDoubleLinKListnodeList;
        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>();
            this.nodeKeyMap=new HashMap, K>();
            this.nodeList=new NodeDoubleLinKList();
            this.capacity=capacity;
        }
        public V get(K key){
            if(this.keyNodeMap.containsKey(key)){
                NoderesNode=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)){
                Nodenode=this.keyNodeMap.get(key);
                node.value=value;
                this.nodeList.moveNodeToTail(node);
            }else{
                NodenewNode=new Node(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() {
            NoderemoveNode=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);
        }

    }

}

类似LRU定时清除缓存的缓存优化算法详解(缓存淘汰策略)_第2张图片

你可能感兴趣的:(技术分享,缓存优化算法,图解缓存优化,LRU)