package datastructure.linkedlist; /** * 用双向链表实现LRU算法 * * @author liuxin * */ public class LRUPageFrame { private static class Node { Node prev; Node next; int pageNum; 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 key * @return */ public void access(int pageNum) { if (isEmpty()) { initFirstNode(pageNum); return; } if (contains(pageNum)) { moveToFirst(pageNum); } else { insert(pageNum); } } private void initFirstNode(int pageNum) { Node node = new Node(pageNum); first = last = node; size++; } private void moveToFirst(int pageNum) { if (isFirst(pageNum)) { return; } if (isLast(pageNum)) { moveLastToFirst(); } else { moveMidToFirst(pageNum); } } private void moveLastToFirst() { Node temp = last; removeLast(); addToFirst(temp); } private void addToFirst(Node temp) { temp.next = first; first.prev = temp; first = temp; size++; } private void moveMidToFirst(int pageNum) { Node node = removeMidNode(pageNum); addToFirst(node); } private Node removeMidNode(int pageNum) { Node temp = getNode(pageNum); temp.prev.next = temp.next; temp.next.prev = temp.prev; temp.next = null; temp.prev = null; size--; return temp; } private void insert(int pageNum) { if (isFill()) { removeLast(); } insertToFirst(pageNum); } private void removeLast() { last = last.prev; last.next = null; size--; } private void insertToFirst(int pageNum) { Node node = new Node(pageNum); addToFirst(node); } private boolean contains(int pageNum) { return indexOf(pageNum) != -1; } private int indexOf(int num) { Node temp = first; for (int i = 0; i < size; i++) { if (temp.pageNum == num) { return i; } temp = temp.next; } return -1; } private Node getNode(int pageNum) { Node temp; temp = first; for (int i = 0; i < size; i++) { if (temp.pageNum == pageNum) { break; } temp = temp.next; } return temp; } private boolean isEmpty() { return size == 0; } private boolean isFirst(int pageNum) { return first.pageNum == pageNum; } private boolean isLast(int pageNum) { return last.pageNum == pageNum; } private boolean isFill() { return size == capacity; } @Override 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(); } }