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 3
If you want a fixed length circular list. You can use a (dynamic) array. Use two variables for houskeeping. One for the position of the next element, one to count the number of elements.
Put: put element on free place. move the position (modulo length). Add 1 to the count unless count equals the lengtht of the list. Get: only if count>0. move the position to the left (modulo length). Decrement the count.
Here is a simple template solution for a circular buffer (FIFO). It does leave one storage space empty, but I think this is a small penalty for the performance and simplicity. I included a simple stress-test.
#include <iostream>
#include <string>
using namespace std;
class E: public std::exception {
const char *_msg;
E(){}; //no default constructor
public:
explicit E(const char *msg) throw(): _msg(msg) {};
const char * what() const throw() {return(_msg);};
};
const int min_size = 2;
const int max_size = 1000;
template<typename T>
class Fifo{
int _head;
int _tail;
int _size;
T* _storage;
public:
explicit Fifo(int size = min_size);
~Fifo(){ delete [] _storage;};
bool is_full() const{
return(((_head+1)%_size) == _tail);
};
bool is_empty() const{
return(_head == _tail);
};
void add_item(const T& item);
const T& get_item();
};
template<typename T>
Fifo<T>::Fifo(int size): _size(size){
if (size < min_size) throw E("Cannot create Fifo less than 2\n");
_head = _tail = 0;
try{
_storage = new T[_size];
}
catch (std::bad_alloc &ba)
{
char e_string[500];
sprintf(e_string, "Cannot allocate memory (%s)\n", ba.what());
throw E(e_string);
}
printf("Constructing Fifo of size %d\n", _size);
}
template <typename T>
void Fifo<T>::add_item(const T& item)
{
if (this->is_full()) throw E("Fifo is full.\n");
_storage[_head] = item;
_head = (_head + 1)%_size;
}
template <typename T>
const T& Fifo<T>::get_item()
{
if (this->is_empty()) throw E("Fifo is empty.\n");
int temp = _tail; //save the current tail
_tail = (_tail+1)%_size; //update tail
return(_storage[temp]);
}
int main()
{
Fifo<int> my_fifo(3);
for (int i = 1, item; i < 50; i++)
{
my_fifo.add_item(i);
my_fifo.add_item(i*10);
item = my_fifo.get_item();
printf("Item: %d\n", item);
item = my_fifo.get_item();
printf("Item: %d\n", item);
}
return 0;
}