/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cyclicbuffer; import java.util.Iterator; import java.util.NoSuchElementException; /** * * @author shay */ public class CyclicBuffer implements Iterable { T[] buffer; // The Buffer array. int bufferSize; // Its size; int firstPtr; // offset to the first entry in the buffer. int lastPtr; // offset to the last entry in the buffer. int numElemStored; // # of elements stored - for the iterator. public class CyclicBufferIterator implements Iterator { private int iterNextPtr = -1; // Used by the iterator: private int elemLeft = 0; public CyclicBufferIterator() { iterNextPtr = firstPtr; elemLeft = numElemStored; } public boolean hasNext() { return(elemLeft > 0); } public T next() { if (hasNext()) { T retVal = (T) buffer[iterNextPtr]; iterNextPtr = nextPtrVal(iterNextPtr); elemLeft--; return(retVal); } throw new NoSuchElementException(); } } public CyclicBuffer(int bufferSize) { this.bufferSize = bufferSize; this.buffer = (T[]) new Object[bufferSize]; this.firstPtr = 0; this.lastPtr = -1; this.numElemStored = 0; } /** * Calculate the next value of a pointer to the buffer: * @param currPtrVal - the current value. * @return - the next value. */ private int nextPtrVal(int currPtrVal) { return ((currPtrVal + 1) % bufferSize); } public void add(T val) { // Calculate the next location: int nextPtr = nextPtrVal(lastPtr); // If reached back to the first stored element in the buffer then // all its entries have been filled; in such case, move the pointer to // to the first element ahead, and don't count the # of entries in the // buffer, if (lastPtr != -1 && nextPtr == firstPtr) firstPtr = nextPtrVal(firstPtr); else numElemStored++; // Add the entry to the next free location. buffer[nextPtr] = val; lastPtr = nextPtr; } public void printValues() { int next = firstPtr; while (true) { System.out.println(buffer[next]); if (next == lastPtr) break; next = nextPtrVal(next); } } @Override public Iterator iterator() { return(new CyclicBufferIterator<>()); } /** * @param args the command line arguments */ public static void main(String[] args) { String[] inpVals = {"111", "2222", "3333", "4444", "5555", "6666", "777"}; //String[] inpVals = {"111", "2222", "3333"}; CyclicBuffer buff = new CyclicBuffer(5); // for (String str : inpVals) // buff.add(str); for (int i = 0; i < 10; i++) { String str = String.format("%1$d%1$d%1$d%1$d%1$d", i); buff.add(str); } // Iterator bufIter = buff.iterator(); // while (bufIter.hasNext()) // { // String str = bufIter.next(); // System.out.println(str); // } for (String str : buff) System.out.println(str); // buff.printValues(); } }