package iotcloud; /** * Circular buffer that holds the live set of slots. * @author Brian Demsky * @version 1.0 */ class SlotBuffer { static final int DEFAULT_SIZE = 16; private Slot[] array; private int head; private int tail; public long oldestseqn; SlotBuffer() { array = new Slot[DEFAULT_SIZE + 1]; head = tail = 0; oldestseqn = 0; } int size() { if (head >= tail) return head - tail; return (array.length + head) - tail; } int capacity() { return array.length - 1; } void resize(int newsize) { if (newsize == (array.length - 1)) return; Slot[] newarray = new Slot[newsize + 1]; int currsize = size(); int index = tail; for (int i = 0; i < currsize; i++) { newarray[i] = array[index]; if ((++index) == array.length) index = 0; } array = newarray; tail = 0; head = currsize; } private void incrementHead() { head++; if (head >= array.length) head = 0; } private void incrementTail() { tail++; if (tail >= array.length) tail = 0; } void putSlot(Slot s) { long checkNum = (getNewestSeqNum() + 1); if (checkNum != s.getSequenceNumber()) { // We have a gap so expunge all our slots oldestseqn = s.getSequenceNumber(); tail = 0; head = 1; array[0] = s; return; } array[head] = s; incrementHead(); if (oldestseqn == 0) { oldestseqn = s.getSequenceNumber(); } if (head == tail) { incrementTail(); oldestseqn++; } } Slot getSlot(long seqnum) { int diff = (int) (seqnum - oldestseqn); int index = diff + tail; if (index < 0) { // Really old message so we dont have it anymore return null; } if (index >= array.length) { if (head >= tail) { return null; } index -= array.length; } if (index >= array.length) { return null; } if (head >= tail && index >= head) { return null; } return array[index]; } long getOldestSeqNum() { return oldestseqn; } long getNewestSeqNum() { return oldestseqn + size() - 1; } }