package com.github.miniyk2012.coding2017.basic.linklist; /** * 用双向链表实现LRU算法 * @author liuxin * */ public class LRUPageFrame { private static class Node { Node prev; Node next; int pageNum; Node() { } Node(int pageNum) { this.pageNum = pageNum; } } private int capacity; private int size; private Node first;// 链表头 private Node last;// 链表尾 public LRUPageFrame(int capacity) { this.capacity = capacity; } /** * 获取缓存中对象 * * @param pageNum: page值 * @return */ public void access(int pageNum) { Node hitNode = get(pageNum); if (null == hitNode) { hitNode = new Node(pageNum); addTop(hitNode); if (size > capacity) { delBottom(); } } else { switchTop(hitNode); } } /** * 获取值为pageNum的Node,如果没有返回null * @param pageNum * @return */ private Node get(int pageNum) { Node currentNode = first; while (currentNode != null) { if (currentNode.pageNum == pageNum) return currentNode; currentNode = currentNode.next; } return null; } /** * 往顶部放一个Node * @param node */ private void addTop(Node node) { size++; if (first == null) { first = last = node; } else { node.next = first; first.prev = node; first = node; } } /** * 把node和顶部做交换 * @param node */ private void switchTop(Node node) { if (node == first) return; Node preNode = node.prev; Node nextNode = node.next; preNode.next = nextNode; if (nextNode != null) { nextNode.prev = preNode; } else { last = preNode; } node.next = node.prev = null; addTop(node); size--; } /** * 把底部的踢掉 */ private void delBottom() { size--; if (last == first) first = null; Node temp = last; last = last.prev; temp.prev = null; last.next = null; } 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(); } /** * 测试双向链表逆序输出 * @return */ public String lastToString(){ StringBuilder buffer = new StringBuilder(); Node node = last; while(node != null){ buffer.append(node.pageNum); node = node.prev; if(node != null){ buffer.append(","); } } return buffer.toString(); } }