码迷,mamicode.com
首页 > 其他好文 > 详细

简易LRU缓存淘汰模拟

时间:2020-01-11 20:23:18      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:style   根据   插入   tab   color   null   name   命中   static   

模拟采用链表保存缓存数据,功能如下

1. 新数据插入到链表头部;

2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;

3. 当链表满的时候,将链表尾部的数据丢弃。

 

假设访问的数据为 Person

public class LRUCache{

    private static int count=0;
    private int capacity;
    private static class Node{
        private static Node head;
        private static Node tail;
        private Person person;
        private Node prev;
        private Node next;

        public Node(Person person){
            this.person = person;
        }
    }

    public void iterator(){
        Node h = Node.head;
        while (h!=null){
            System.out.println(h.person.getId()+" "+h.person.getName());
            h = h.next;
        }
    }

    public LRUCache(int capacity){
        this.capacity = capacity;
    }


    public Person getPersonById(int id){
        Node h = Node.head;
        if (h==null)return null;
        while (h!=null){
            if (h.person.getId() == id){
                Person target = h.person;
                moveToHead(h.person);
                deleteNode(h);
                return target;
            }
            h = h.next;
        }
        return null;
    }

    public void addToList(Person person){
        if (capacity == count){
            Node.tail =  Node.tail.prev;
            Node.tail.next = null;
        }
        moveToHead(person);
        count++;
    }

    private void moveToHead(Person person){
        if (Node.head == null){
            Node newNode = new Node(person);
            Node.head = newNode;
            Node.tail = newNode;
            return;
        }
        Node h = Node.head;
        Node newNode = new Node(person);
        newNode.next = h;
        h.prev = newNode;
        Node.head = newNode;
    }

    private void deleteNode(Node node){
        if (node == Node.head){
            Node.head = node.next;
            Node.head.prev = null;
        }

        if (node == Node.tail){
            Node.tail =  node.prev;
            Node.tail.next = null;
        }
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }
}

模拟获取数据:

public class PersonList {

    private LRUCache cache;
    public PersonList(LRUCache lruCache){
        this.cache = lruCache;
    }

    public LRUCache getCache(){
        return cache;
    }

    public Person getPersonById(int id){
        Person p;
        if ((p = cache.getPersonById(id) )== null){ 
            //模拟假设从数据库中根据id查出对应的人
            p= new Person(id,"p"+id,18,1);
            cache.addToList(p);
        }
        return p;
    }
}

运行:

public class Test {

    public static void main(String[] args){

        PersonList personList = new PersonList(new LRUCache(3));
        Person p1 = personList.getPersonById(1);
        personList.getCache().iterator();
        System.out.println("-------------------");
        Person p2 = personList.getPersonById(2);
        personList.getCache().iterator();
        System.out.println("-------------------");
        Person p3 = personList.getPersonById(3);
        personList.getCache().iterator();
        System.out.println("-------------------");
        Person p5 = personList.getPersonById(2);
        personList.getCache().iterator();
        System.out.println("-------------------");
        Person p4 = personList.getPersonById(4);
        personList.getCache().iterator();

    }

运行结果:
1 p1
-------------------
2 p2
1 p1
-------------------
3 p3
2 p2
1 p1
-------------------
2 p2
3 p3
1 p1
-------------------
4 p4
2 p2
3 p3

LRU有好多种实现的方式,一般可以用双链表+hashtable,如果只用双链表的话,查找的时间复杂度为O(n),效率较慢

简易LRU缓存淘汰模拟

标签:style   根据   插入   tab   color   null   name   命中   static   

原文地址:https://www.cnblogs.com/zwb1/p/12180804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!