package lru; /** * Created by william on 2017/3/31. * 1. 新数据插入到链表头部; * 2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部; * 3. 当链表满的时候,将链表尾部的数据丢弃。 */ public class LRUPageFrame { private static class Node { Node prev; Node next; int pageNum; Node() { } @Override public String toString() { return pageNum + ""; } } private int capacity; private Node first;// 链表头 private Node last;// 链表尾 private int size; private void removeLast() { if (last != null) { if (size == 1) { first = last = null; size = 0; } else { last = last.prev; last.next = null; size--; } } } private void remove(Integer pageNum) { for (Node temp = first; temp != null; temp = temp.next) { if (temp.pageNum == pageNum) { unlink(temp); } } } private void unlink(Node node) { final Node prev = node.prev; final Node next = node.next; if (prev == null) { first = next; size--; } else if (next == null) removeLast(); else { node.next.prev = prev; node.prev.next = next; size--; } } private void addFirst(Integer pageNum) { Node newNode = new Node(); newNode.pageNum = pageNum; if (first == null) { first = last = newNode; } else { newNode.next = first; first.prev = newNode; first = newNode; //在插入第二个元素时设置last元素的前项 if (size == 1) last.prev = first; } size++; } private boolean contains(Integer pageNum) { Node temp = first; while (temp != null) { if (temp.pageNum == pageNum) return true; temp = temp.next; } return false; } public LRUPageFrame(int capacity) { this.capacity = capacity; } /** * 获取缓存中对象 * * @param pageNum * @return */ public void access(int pageNum) { //存在链表元素 if (this.contains(pageNum)) { remove(pageNum); addFirst(pageNum); } else { //不存在 if (size == capacity) removeLast(); addFirst(pageNum); } } 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(); } }