package com.aaront.exercise.basic; import java.util.Optional; /** * 用双向链表实现LRU算法 * * @author tonyhui */ public class LRUPageFrame { private static class Node { Node prev; Node next; int pageNum; Node() { } } private int capacity; private int size = 0; private Node first;// 链表头 private Node last;// 链表尾 public LRUPageFrame(int capacity) { this.capacity = capacity; } /** * 获取缓存中对象 */ public void access(int pageNum) { Optional<Node> node = getNodeByPageNum(pageNum); node.map(r -> { delete(r); addFirst(r); return ""; }).orElseGet(() -> { Node newNode = new Node(); newNode.pageNum = pageNum; addFirst(newNode); if (size >= capacity) { delete(last); } else { size++; } return ""; }); } private Optional<Node> getNodeByPageNum(int pageNum) { Node node = first; while (node != null) { if (node.pageNum == pageNum) return Optional.of(node); node = node.next; } return Optional.empty(); } private void delete(Node node) { if (node == null) return; if (node == first) { deleteFirst(); return; } if (node == last) { deleteLast(); return; } Node prevNode = node.prev; Node nextNode = node.next; prevNode.next = nextNode; nextNode.prev = prevNode; node.next = null; node.prev = null; } private void deleteFirst() { if (first == null) return; first = first.next; first.prev = null; } private void deleteLast() { if (last == null) return; last = last.prev; last.next = null; } private void addFirst(Node node) { if (node == null) return; if (first == null) { first = node; last = node; } else { node.next = first; first.prev = node; first = node; } } public String toString() { StringBuilder buffer = new StringBuilder(); Node node = first; while (node != null) { buffer.append(node.pageNum); node = node.next; if (node != null) { buffer.append(","); } } return buffer.toString(); } }