    001    /**
    002     *
    003     */
    004    package calhoun.analysis.crf.solver;
    005
    006    import java.util.Iterator;
    007
    008    /** Utility class that implements a FIFO buffer with constant time adds, removes,
    009     * and accesses to any position using a circular buffer in an array.
    010     */
    011    public final class RecyclingBuffer<T> {
    012            public T[] array;
    013            public int length;
    014            public int currentStart = length;
    015
    016            public RecyclingBuffer(final T[] arg) {
    017                    this.array = arg;
    018                    length = array.length;
    019            }
    020
    021            public final T get(final int i) {
    022                    if(i >= length)
    023                            throw new ArrayIndexOutOfBoundsException(i);
    024                    return array[(currentStart+i)%length];
    025            }
    026
    027            public final void set(final int i, final T val) {
    028                    if(i >= length)
    029                            throw new ArrayIndexOutOfBoundsException(i);
    030                    array[(currentStart+i)%length] = val;
    031            }
    032
    033            public final T addFirst(final T t) {
    034                    currentStart = (currentStart+length-1)%length;
    035                    T ret = array[currentStart];
    036                    array[currentStart] = t;
    037                    return ret;
    038            }
    039
    040            public final int getTotalSize() {
    041                    return length;
    042            }
    043
    044            final class RecyclingBufferIterator implements Iterator<T> {
    045                    int current = 0;
    046                    public final boolean hasNext() {
    047                            return current < length;
    048                    }
    049                    public final T next() {
    050                            T ret = get(current);
    051                            ++current;
    052                            return ret;
    053                    }
    054
    055                    public final void remove() {
    056                            throw new UnsupportedOperationException();
    057                    }
    058            }
    059    }