package mj.ocraptor.events; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.NoSuchElementException; public class RingBuffer<E> implements Collection<E> { private static final int DEFAULT_CAPACITY = 10; private E[] elementData; private int capacity; private int size; private int index; public RingBuffer(int capacity) throws IllegalArgumentException { if (capacity <= 0) throw new IllegalArgumentException("Illegal Capacity : " + capacity); this.capacity = capacity; clear(); } /** * {@inheritDoc} * @see Object#RingBuffer() */ public RingBuffer() { this(DEFAULT_CAPACITY); } /** * * * @param c * * @throws NullPointerException */ @SuppressWarnings("unchecked") public RingBuffer(Collection<? extends E> c) throws NullPointerException { capacity = c.size(); size = capacity; index = 0; elementData = c.toArray((E[]) new Object[capacity]); } /** * {@inheritDoc} * @see Collection#clear() */ @SuppressWarnings("unchecked") public void clear() { elementData = (E[]) new Object[capacity]; size = 0; index = 0; } /** * {@inheritDoc} * @see Collection#add(E) */ public boolean add(E o) { index = (capacity + --index) % capacity; elementData[index] = o; if (size < capacity) size++; return true; } /** * {@inheritDoc} * @see Collection#contains(Object) */ public boolean contains(Object o) { for (Object e : this) if (o == null ? e == null : o.equals(e)) return true; return false; } /** * {@inheritDoc} * @see Collection#containsAll(Collection<?>) */ public boolean containsAll(Collection<?> c) { if (c.size() > size) return false; for (Object o : c) if (!contains(o)) return false; return true; } /** * {@inheritDoc} * @see Collection#isEmpty() */ public boolean isEmpty() { return size == 0; } /** * {@inheritDoc} * @see Collection#size() */ public int size() { return size; } /** * * * @return */ public int capacity() { return capacity; } /** * {@inheritDoc} * @see Collection#iterator() */ public Iterator<E> iterator() { return new RingBufferIterator<E>(this, index, size); } /** * {@inheritDoc} * @see Collection#toArray() */ public Object[] toArray() { Object[] a = new Object[size]; int i = 0; for (E element : this) a[i++] = element; return a; } /** * {@inheritDoc} * @see Collection#toArray(T[]) */ @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) throws NullPointerException, ArrayStoreException { if (a.length < size) return (T[]) Arrays.copyOf(toArray(), size, a.getClass()); System.arraycopy(toArray(), 0, a, 0, size); if (a.length > size) a[size] = null; return a; } /** * {@inheritDoc} * @see Collection#addAll(Collection<E>) */ public boolean addAll(Collection<? extends E> c) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * @see Collection#remove(Object) */ public boolean remove(Object o) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * @see Collection#removeAll(Collection<?>) */ public boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * @see Collection#retainAll(Collection<?>) */ public boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * @see Object#toString() */ public String toString() { return Arrays.toString(toArray()); } /** * */ private class RingBufferIterator<T> implements Iterator<T> { private int index; private int size; private RingBuffer<T> rb; /** * * * @param rb * @param index * @param size */ private RingBufferIterator(RingBuffer<T> rb, int index, int size) { this.index = index; this.size = size; this.rb = rb; } /** * {@inheritDoc} * @see Iterator#hasNext() */ public boolean hasNext() { return size > 0; } /** * {@inheritDoc} * @see Iterator#next() */ public T next() throws NoSuchElementException { if (!hasNext()) throw new NoSuchElementException(); T element = rb.elementData[index]; size--; index = (capacity + ++index) % rb.capacity; return element; } /** * {@inheritDoc} * @see Iterator#remove() */ public void remove() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } } /** * * * @return */ public int length() { int count = 0; for (E e : elementData) { if (e != null) { count++; } } return count; } }