package code04; /** * 用双向链表实现LRU算法 */ public class LRUPageFrame { private class Node { Node prev; Node next; int pageNum; Node() { } } private int size; private int capacity; private Node first;// 链表头 private Node last;// 链表尾 public LRUPageFrame(int capacity) { this.capacity = capacity; this.size = 0; } /** * 获取缓存中对象 * 1、如果缓存中不存在,则直接加入表头 * 2、如果缓存中存在,则把该对象移动到表头 * @param pageNum * @return */ public void access(int pageNum) { Node node = hasContains(pageNum); if(node != null){ moveToHead(node); }else { addToHead(pageNum); } } /** * 对象是否存在缓存中,如存在则返回该对象在链表中的位置,否则返回null * @return */ private Node hasContains(int key){ Node node = this.first; while (node != null){ if(node.pageNum == key){ return node; } node = node.next; } return node; } /** * 对象加入表头,先先判断缓存是否已经满了 * @return */ private void addToHead(int key){ Node node = new Node(); node.pageNum = key; if(size < capacity){ addFirst(node); }else { removeLast(); addFirst(node); } } /** * 对象移动到表头 * @return */ private void moveToHead(Node node){ if(node == first){ return; } if(node == last){ node.next = first; first.prev = node; first = node; last = node.prev; last.next = null; node.prev = null; return; } node.prev.next = node.next; node.next.prev = node.prev; node.next = first; node.prev = null; first.prev = node; first = node; } /** * 删除表尾 * @return */ private void removeLast(){ if(last != null){ Node newLast = last.prev; last.prev = null; last = newLast; last.next = null; size --; } } /** * 添加元素到表头 * @return */ private void addFirst(Node node){ //0个节点 if(first == null){ first = node; last = node; size ++; return; } //一个节点 else if(first == last){ first = node; first.next = last; last.prev = first; size ++; return; }else { node.next = first; first.prev = node; first = node; size ++; } } /** * 当前链表空间 * @return */ public int getSize() { return size; } 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(); } }