• iv018-redis的LRU算法简介


    LRU:least recently used 最近最少使用的
    LRU的算法核心是哈希链表(本质就是HashMap+DoubleLinkedList)

    编码实现:

    public class LRUDemo<K, V> {
    
        private int cacheSize;
    
        private Map<K, Node<K, V>> map;
    
        private DoubleLinkList<K, V> linkList;
    
        public LRUDemo(int cacheSize) {
            this.cacheSize = cacheSize;
            map = new HashMap<>();
            linkList = new DoubleLinkList<>();
        }
    
        public V get(K key) {
            if (!map.containsKey(key)) {
                return null;
            }
            Node<K, V> node = map.get(key);
            linkList.removeNode(node);
            linkList.addHead(node);
            return node.value;
        }
    
        public void put(K key, V value) {
            if (map.containsKey(key)) {
                Node<K, V> node = map.get(key);
                node.value = value;
                linkList.removeNode(node);
                linkList.addHead(node);
            } else {
                if (map.size() >= cacheSize) {
                    linkList.removeNode(linkList.getLastNode());
                }
                Node<K, V> newNode = new Node<>(key, value);
                linkList.addHead(newNode);
                map.put(key, newNode);
            }
        }
    
        class Node<K, V> {
            K key;
            V value;
            Node<K, V> prev;
            Node<K, V> next;
    
            Node() {
                prev = next = null;
            }
    
            Node(K key, V value) {
                this.key = key;
                this.value = value;
                prev = next = null;
            }
    
            @Override
            public String toString() {
                return "Node{" +
                        "key=" + key +
                        ", value=" + value +
                        '}';
            }
        }
    
        class DoubleLinkList<K, V> {
            Node<K, V> head;
            Node<K, V> tail;
    
            DoubleLinkList() {
                head = new Node<>();
                tail = new Node<>();
                head.next = tail;
                tail.prev = head;
            }
    
            public void addHead(Node<K, V> node) {
                node.prev = head;
                node.next = head.next;
                head.next.prev = node;
                head.next = node;
            }
    
            public void removeNode(Node<K, V> node) {
                if (node != null && node != head && node != tail) {
                    node.prev.next = node.next;
                    node.next.prev = node.prev;
                    node.prev = null;
                    node.next = null;
                }
            }
    
            public Node<K, V> getLastNode() {
                return tail.prev != head ? tail.prev : null;
            }
    
            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder("[");
                Node<K, V> node = head.next;
                while (node != null && node != tail) {
                    sb.append(node.key);
                    node = node.next;
                    if (node != tail) {
                        sb.append(",");
                    }
                }
                return sb.append("]").toString();
            }
        }
    
        public static void main(String[] args) {
            LRUDemo<Integer, Integer> lruDemo = new LRUDemo<>(3);
            lruDemo.put(1, 1);
            lruDemo.put(2, 2);
            lruDemo.put(3, 3);
            System.out.println(lruDemo.linkList);
            lruDemo.put(4, 4);
            System.out.println(lruDemo.linkList);
            lruDemo.put(3, 3);
            System.out.println(lruDemo.linkList);
            lruDemo.put(3, 33);
            System.out.println(lruDemo.linkList);
            lruDemo.put(3, 3);
            System.out.println(lruDemo.linkList);
            lruDemo.put(5, 5);
            System.out.println(lruDemo.linkList);
            lruDemo.get(4);
            System.out.println(lruDemo.linkList);
        }
    }
    

    运行结果:

    [3,2,1]
    [4,3,2]
    [3,4,2]
    [3,4,2]
    [3,4,2]
    [5,3,4]
    [4,5,3]
    
  • 相关阅读:
    快学scala习题解答--第五章 类
    从头认识java-18.2 主要的线程机制(2)-Executors的使用
    关于Bootstrap的理解
    Raw-OS源代码分析之idle任务
    Scilab 的画图函数(3)
    HDU2586.How far away ?——近期公共祖先(离线Tarjan)
    Codeforces Round #311 (Div. 2) A,B,C,D,E
    presto访问 Azure blob storage
    Presto集群安装配置
    Presto架构及原理
  • 原文地址:https://www.cnblogs.com/everyingo/p/14565111.html
Copyright © 2020-2023  润新知