How do I implement a circular list that overwrites the oldest entry when it's full?
For a little background, I want to use a circular list within GWT; so using a 3rd party lib is not what I want.
What Does Ring Buffer Mean? A ring buffer is a data structure that is treated as circular although it its implementation is linear. A circular buffer is typically used as a data queue. A circular buffer is a popular way to implement a data stream because the code can be compact.
Circular buffers (also known as ring buffers) are fixed-size buffers that work as if the memory is contiguous & circular in nature. As memory is generated and consumed, data does not need to be reshuffled – rather, the head/tail pointers are adjusted.
A very simple implementation, expressed in C. Implements a circular buffer style FIFO queue. Could be made more generic by creating a structure containing the queue size, queue data, and queue indexes (in and out), which would be passed in with the data to add or remove from the queue. These same routines could then handle several queues. Also note that this allows queues of any size, although speedups can be used if you use powers of 2 and customize the code further.
/* Very simple queue * These are FIFO queues which discard the new data when full. * * Queue is empty when in == out. * If in != out, then * - items are placed into in before incrementing in * - items are removed from out before incrementing out * Queue is full when in == (out-1 + QUEUE_SIZE) % QUEUE_SIZE; * * The queue will hold QUEUE_ELEMENTS number of items before the * calls to QueuePut fail. */ /* Queue structure */ #define QUEUE_ELEMENTS 100 #define QUEUE_SIZE (QUEUE_ELEMENTS + 1) int Queue[QUEUE_SIZE]; int QueueIn, QueueOut; void QueueInit(void) { QueueIn = QueueOut = 0; } int QueuePut(int new) { if(QueueIn == (( QueueOut - 1 + QUEUE_SIZE) % QUEUE_SIZE)) { return -1; /* Queue Full*/ } Queue[QueueIn] = new; QueueIn = (QueueIn + 1) % QUEUE_SIZE; return 0; // No errors } int QueueGet(int *old) { if(QueueIn == QueueOut) { return -1; /* Queue Empty - nothing to get*/ } *old = Queue[QueueOut]; QueueOut = (QueueOut + 1) % QUEUE_SIZE; return 0; // No errors }
Use a linked list. Maintain separate pointers for the head and tail. Pop from the head of the list, push onto the tail. If you want it circular, just make sure the new tail always points to the head.
I can understand why you might want to implement a FIFO using a linked list, but why make it a circular list?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With