package au.gov.amsa.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
import net.jcip.annotations.NotThreadSafe;
/**
* Non-threadsafe implementation of a Ring Buffer. Does not accept nulls.
*
* @param <T>
*/
@NotThreadSafe
public class RingBuffer<T> implements Queue<T> {
private final T[] list;
private int start;
private int finish;
@SuppressWarnings("unchecked")
private RingBuffer(int size) {
list = (T[]) new Object[size + 1];
}
public static <T> RingBuffer<T> create(int size) {
return new RingBuffer<T>(size);
}
@Override
public void clear() {
finish = start;
}
@Override
public Iterator<T> iterator() {
final int _start = start;
final int _finish = finish;
return new Iterator<T>() {
int i = _start;
@Override
public boolean hasNext() {
return i != _finish;
}
@Override
public T next() {
T value = list[i];
i = (i + 1) % list.length;
return value;
}
};
}
@Override
public T peek() {
if (start == finish)
return null;
else
return list[start];
}
public boolean isEmpty() {
return start == finish;
}
public int size() {
if (start <= finish)
return finish - start;
else
return finish - start + list.length;
}
public int maxSize() {
return list.length - 1;
}
@Override
public boolean contains(Object o) {
return notImplemented();
}
@Override
public Object[] toArray() {
return notImplemented();
}
@Override
public <S> S[] toArray(S[] a) {
return notImplemented();
}
@Override
public boolean remove(Object o) {
return notImplemented();
}
@Override
public boolean containsAll(Collection<?> c) {
return notImplemented();
}
private static <T> T notImplemented() {
throw new RuntimeException("Not implemented");
}
@Override
public boolean addAll(Collection<? extends T> c) {
for (T t : c)
add(t);
return true;
}
@Override
public boolean removeAll(Collection<?> c) {
return notImplemented();
}
@Override
public boolean retainAll(Collection<?> c) {
return notImplemented();
}
@Override
public boolean add(T t) {
if (offer(t))
return true;
else
throw new IllegalStateException("Cannot add to queue because is full");
}
@Override
public boolean offer(T t) {
if (t == null)
throw new NullPointerException();
int currentFinish = finish;
finish = (finish + 1) % list.length;
if (finish == start) {
return false;
} else {
list[currentFinish] = t;
return true;
}
}
@Override
public T remove() {
T t = poll();
if (t == null)
throw new NoSuchElementException();
else
return t;
}
@Override
public T poll() {
if (start == finish) {
return null;
} else {
T value = list[start];
// don't hold a reference to a popped value
list[start] = null;
start = (start + 1) % list.length;
return value;
}
}
@Override
public T element() {
return notImplemented();
}
}