package org.coding.four.lru;
/**
* 用双向链表实现LRU(最近最少使用)算法
* @author liuxin
*
*/
public class LRUPageFrame {
private static class Node {
Node prev;
Node next;
int pageNum;
Node() {
}
}
private int capacity;
private Node first;// 链表头
private Node last;// 链表尾
public LRUPageFrame(int capacity) {
this.capacity = capacity;
}
/**
* 获取缓存中对象
*
* @param key
* @return
*/
public void access(int pageNum) {
Node node = findNode(pageNum);
if(node == null) {
addNode(pageNum);
} else {
moveExistNode(node);
}
}
private void moveExistNode(Node node) {
if(node == first) {
return ;
}
if(node == last) {
removeLastNode();
node.next = first;
first.prev = node;
first = node;
return;
}
node.prev.next = node.next;
node.next.prev = node.prev;
node.prev = null;
node.next = first;
first = node;
}
private void addNode(int pageNum) {
if(first == null) {
first = new Node();
first.pageNum = pageNum;
last = first;
}else {
if(isFull()) {
removeLastNode();
push(pageNum);
}else {
push(pageNum);
}
}
}
private boolean isFull() {
return getSize() == capacity;
}
private void removeLastNode() {
last = last.prev;
last.next = null;
}
private void push(int pageNum) {
Node node = new Node();
node.pageNum = pageNum;
node.next = first;
first.prev = node;
first = node;
}
private Node findNode(int pageNum) {
if(first == null) {
return null;
}
if(first.pageNum == pageNum) {
return first;
}
Node node = first;
while(node.next != null) {
node = node.next;
if(node.pageNum == pageNum) {
return node;
}
}
return null;
}
private int getSize() {
if(first == null) {
return 0;
}
Node node = first;
int size = 1;
while(node.next != null) {
size++;
node = node.next;
}
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();
}
}