package org.orbeon.oxf.cache;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* This is a minimal linked list optimized for the cache.
*/
public class CacheLinkedList<E> implements Iterable<E> {
public static class ListEntry<E> {
public E element;
public ListEntry<E> next;
public ListEntry<E> prev;
public ListEntry() {
}
public ListEntry(E element, ListEntry next, ListEntry previous) {
this.element = element;
this.next = next;
this.prev = previous;
}
}
private ListEntry<E> listHeader;
private int size;
public CacheLinkedList() {
clear();
}
public void clear() {
listHeader = new ListEntry<E>();
listHeader.next = listHeader.prev = listHeader;
size = 0;
}
public E getFirst() {
return listHeader.next.element;
}
public E getLast() {
return listHeader.prev.element;
}
public ListEntry getLastEntry() {
return listHeader.prev;
}
public E removeLast() {
final E last = listHeader.prev.element;
remove(listHeader.prev);
return last;
}
public ListEntry<E> addFirst(E o) {
return addBefore(o, listHeader.next);
}
private ListEntry<E> addBefore(E o, ListEntry<E> e) {
final ListEntry<E> newEntry = new ListEntry<E>(o, e, e.prev);
newEntry.prev.next = newEntry;
newEntry.next.prev = newEntry;
size++;
return newEntry;
}
public void remove(ListEntry<E> e) {
if (e == listHeader)
throw new NoSuchElementException();
e.prev.next = e.next;
e.next.prev = e.prev;
size--;
}
public int size() {
return size;
}
public Iterator<E> iterator() {
return new Iterator<E>() {
private ListEntry<E> currentEntry = listHeader.next;
public boolean hasNext() {
return currentEntry != null && currentEntry.element != null;
}
public E next() {
final E result = currentEntry.element;
currentEntry = currentEntry.next;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public Iterator<E> reverseIterator() {
return new Iterator<E>() {
private ListEntry<E> currentEntry = listHeader.prev;
public boolean hasNext() {
return currentEntry != null && currentEntry.element != null;
}
public E next() {
final E result = currentEntry.element;
currentEntry = currentEntry.prev;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}