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    }