package de.skuzzle.polly.tools.collections;
import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Queue;
public class ArrayRingBuffer<T> implements Queue<T> {
private final T[] buffer;
private final int cap;
private int size;
private int start;
private int modCount;
@SuppressWarnings("unchecked")
public ArrayRingBuffer(int capacity) {
this.buffer = (T[]) new Object[capacity];
this.cap = capacity;
this.start = 0;
this.size= 0;
}
public boolean isFilled() {
return this.size == this.cap - 1;
}
@Override
public int hashCode() {
return Arrays.hashCode(this.buffer) + 31 * this.size + 37 * this.start;
}
@Override
public boolean equals(Object o) {
ArrayRingBuffer<?> other = null;
return o == this || o != null &&
o instanceof ArrayRingBuffer &&
Arrays.equals((other = (ArrayRingBuffer<?>) o).buffer, this.buffer) &&
other.size == this.size &&
other.start == this.start;
}
@Override
public String toString() {
final StringBuilder b = new StringBuilder();
b.append("[");
final Iterator<T> it = this.iterator();
while (it.hasNext()) {
final T next = it.next();
if (next != this) {
b.append(next.toString());
} else {
b.append("[...]");
}
if (it.hasNext()) {
b.append(", ");
}
}
b.append("]");
return b.toString();
}
@Override
public boolean addAll(Collection<? extends T> c) {
for (T t : c) {
this.add(t);
}
return true;
}
@Override
public void clear() {
this.start = 0;
this.size = 0;
}
@Override
public boolean contains(Object o) {
for (Object obj : this.buffer) {
if (obj != null && obj.equals(o)) {
return true;
}
}
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object obj : c) {
if (!this.contains(obj)) {
return false;
}
}
return true;
}
@Override
public boolean isEmpty() {
return this.size == 0;
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
int modc = modCount;
int r = start;
int steps = 0;
final int maxSteps = size;
@Override
public boolean hasNext() {
return this.steps < this.maxSteps;
}
@Override
public T next() {
if (this.modc != modCount) {
throw new ConcurrentModificationException();
} else if (!hasNext()) {
throw new NoSuchElementException();
}
final int ri = this.r;
this.r = (this.r + 1) % cap;
++this.steps;
return buffer[ri];
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
return this.size;
}
@Override
public Object[] toArray() {
final Object[] result = new Object[this.size];
int i = 0;
for (Object o : this) {
result[i++] = o;
}
return result;
}
@SuppressWarnings("unchecked")
@Override
public <E> E[] toArray(E[] a) {
if (a.length < this.size) {
a = (E[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), this.size);
}
int i = 0;
for (T o : this) {
a[i++] = (E) o;
}
return a;
}
@Override
public boolean add(T e) {
++this.modCount;
final int next = (this.start + this.size) % this.cap;
if (this.size != this.cap) {
this.size++;
} else {
this.start = (next + 1) % this.cap;
}
this.buffer[next] = e;
return true;
}
@Override
public T element() {
if (this.isEmpty()) {
throw new NoSuchElementException();
}
return this.buffer[this.start];
}
@Override
public boolean offer(T e) {
return this.add(e);
}
@Override
public T peek() {
if (this.isEmpty()) {
return null;
}
return this.buffer[this.start];
}
@Override
public T poll() {
if (this.isEmpty()) {
return null;
}
++this.modCount;
final int r = this.start;
this.start = (this.start + 1) % this.cap;
--this.size;
return this.buffer[r];
}
@Override
public T remove() {
if (this.isEmpty()) {
throw new NoSuchElementException();
}
return this.poll();
}
}