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


//设计一个类似于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){

                    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定时清除缓存的缓存优化算法详解(缓存淘汰策略))