1 // Larbin
2 // Sebastien Ailleret
3 // 09-11-99 -> 01-12-01
4 
5 /* standard fifo in RAM WITHOUT synchronisation */
6 
7 #ifndef FIFO_H
8 #define FIFO_H
9 
10 template <class T>
11 class Fifo {
12  public:
13   uint in, out;
14   uint size;
15   T **tab;
16 
17   /* Specific constructor */
18   Fifo (uint size=maxUrlsBySite);
19 
20   /* Destructor */
21   ~Fifo ();
22 
23   /* give the first object and let it in */
read()24   inline T* read () { return tab[out]; }
25 
26   /* read the first obj if exist */
27   T *tryRead ();
28 
29   /* get the first object */
30   T *get ();
31 
32   /* get the first object (non totally blocking)
33    * return NULL if there is none
34    */
35   T *tryGet ();
36 
37   /* add an object in the Fifo */
38   void put (T *obj);
39 
40   /* put an obj that has just been get
41    * this function must be called only to put back an obj
42    *    that has just been tken with get */
43   void rePut (T *obj);
44 
45   /* how many items are there inside ? */
46   int getLength ();
47 
48   /* is this fifo empty ? */
isEmpty()49   inline bool isEmpty () { return in == out; }
50 };
51 
52 template <class T>
Fifo(uint size)53 Fifo<T>::Fifo (uint size) {
54   tab = new T*[size];
55   this->size = size;
56   in = 0;
57   out = 0;
58 }
59 
60 template <class T>
~Fifo()61 Fifo<T>::~Fifo () {
62   delete [] tab;
63 }
64 
65 template <class T>
tryRead()66 T *Fifo<T>::tryRead () {
67   if (in == out) {
68     return NULL;
69   } else {
70     return tab[out];
71   }
72 }
73 
74 template <class T>
get()75 T *Fifo<T>::get () {
76   T *tmp;
77   assert (in != out);
78   tmp = tab[out];
79   out = (out + 1) % size;
80   return tmp;
81 }
82 
83 template <class T>
tryGet()84 T *Fifo<T>::tryGet () {
85   T *tmp = NULL;
86   if (in != out) {
87 	// The stack is not empty
88 	tmp = tab[out];
89 	out = (out + 1) % size;
90   }
91   return tmp;
92 }
93 
94 template <class T>
put(T * obj)95 void Fifo<T>::put (T *obj) {
96   tab[in] = obj;
97   in = (in + 1) % size;
98   if (in == out) {
99     T **tmp;
100     tmp = new T*[2*size];
101     for (uint i=out; i<size; i++) {
102       tmp[i] = tab[i];
103     }
104     for (uint i=0; i<in; i++) {
105       tmp[i+size] = tab[i];
106     }
107     in += size;
108     size *= 2;
109     delete [] tab;
110     tab = tmp;
111   }
112 }
113 
114 template <class T>
rePut(T * obj)115 void Fifo<T>::rePut (T *obj) {
116   out = (out + size - 1) % size;
117   tab[out] = obj;
118 }
119 
120 template <class T>
getLength()121 int Fifo<T>::getLength () {
122   return (in + size - out) % size;
123 }
124 
125 #endif // FIFO_H
126