Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Formers simgrid fifo : when real O(1) is needed... The way I'm gonna use
[simgrid.git] / src / xbt / fifo.c
1 /* Authors: Arnaud Legrand                                                  */
2
3 /* This program is free software; you can redistribute it and/or modify it
4    under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include <stdlib.h>
7 #include "xbt_fifo_private.h"
8
9 /*
10  * xbt_fifo_new()
11  */
12 xbt_fifo_t xbt_fifo_new(void)
13 {
14   xbt_fifo_t fifo;
15   fifo = (xbt_fifo_t) calloc(1, sizeof(struct xbt_fifo));
16   return fifo;
17 }
18
19 /*
20  * xbt_fifo_free()
21  */
22 void xbt_fifo_free(xbt_fifo_t l)
23 {
24   xbt_fifo_item_t b, tmp;
25
26   for (b = xbt_fifo_getFirstitem(l); b;
27        tmp = b, b = b->next, xbt_fifo_freeitem(tmp));
28   free(l);
29   return;
30 }
31
32 /*
33  * xbt_fifo_push()
34  * at the tail
35  */
36 void xbt_fifo_push(xbt_fifo_t l, void *t)
37 {
38   xbt_fifo_item_t new;
39
40   (l->count)++;
41   new = xbt_fifo_newitem();
42   new->content = t;
43   if (l->head == NULL) {
44     l->head = new;
45     l->tail = new;
46     return;
47   }
48   new->prev = l->tail;
49   new->prev->next = new;
50   l->tail = new;
51   return;
52 }
53
54 /*
55  * xbt_fifo_pop()
56  * from the tail
57  */
58 void *xbt_fifo_pop(xbt_fifo_t l)
59 {
60   xbt_fifo_item_t item;
61   void *content;
62
63   if (l->tail == NULL)
64     return NULL;
65
66   item = l->tail;
67   content = item->content;
68
69   l->tail = item->prev;
70   if (l->tail == NULL)
71     l->head = NULL;
72   else
73     l->tail->next = NULL;
74
75   xbt_fifo_freeitem(item);
76   (l->count)--;
77   return content;
78 }
79
80 /*
81  * xbt_fifo_unshift()
82  * at the head
83  */
84 void xbt_fifo_unshift(xbt_fifo_t l, void *t)
85 {
86   xbt_fifo_item_t new;
87
88   (l->count)++;
89   new = xbt_fifo_newitem();
90   new->content = t;
91   if (l->head == NULL) {
92     l->head = new;
93     l->tail = new;
94     return;
95   }
96   new->next = l->head;
97   new->next->prev = new;
98   l->head = new;
99   return;
100 }
101
102 /*
103  * xbt_fifo_shift()
104  * from the head
105  */
106 void *xbt_fifo_shift(xbt_fifo_t l)
107 {
108   xbt_fifo_item_t item;
109   void *content;
110
111   if (l->head == NULL)
112     return NULL;
113
114   item = l->head;
115   content = item->content;
116
117   l->head = item->next;
118   if (l->head == NULL)
119     l->tail = NULL;
120   else
121     l->head->prev = NULL;
122
123   xbt_fifo_freeitem(item);
124   (l->count)--;
125   return content;
126 }
127
128 /*
129  * xbt_fifo_remove()
130  *   removes an xbt_fifo_item_t using its content from the xbt_fifo 
131  */
132 void xbt_fifo_remove(xbt_fifo_t l, void *t)
133 {
134   xbt_fifo_item_t current, current_next;
135
136
137   for (current = l->head; current; current = current_next) {
138     current_next = current->next;
139     if (current->content != t)
140       continue;
141     /* remove the item */
142     xbt_fifo_remove_item(l, current);
143     /* WILL NOT REMOVE DUPLICATES */
144     break;
145   }
146   return;
147 }
148
149 /*
150  * xbt_fifo_remove_item()
151  *   removes a given xbt_fifo_item_t from the xbt_fifo
152  */
153 void xbt_fifo_remove_item(xbt_fifo_t l, xbt_fifo_item_t current)
154 {
155   if (l->head == l->tail) {     /* special case */
156       l->head = NULL;
157       l->tail = NULL;
158       xbt_fifo_freeitem(current);
159       (l->count)--;
160       return;
161     }
162
163     if (current == l->head) {   /* It's the head */
164       l->head = current->next;
165       l->head->prev = NULL;
166       xbt_fifo_freeitem(current);
167     } else if (current == l->tail) {    /* It's the tail */
168       l->tail = current->prev;
169       l->tail->next = NULL;
170       xbt_fifo_freeitem(current);
171     } else {                    /* It's in the middle */
172       current->prev->next = current->next;
173       current->next->prev = current->prev;
174       xbt_fifo_freeitem(current);
175     }
176     (l->count)--;
177 }
178
179 /*
180  * xbt_fifo_is_in()
181  */
182 int xbt_fifo_is_in(xbt_fifo_t f, void *content)
183 {
184   xbt_fifo_item_t item = xbt_fifo_getFirstitem(f);
185   while (item) {
186     if (item->content == content)
187       return 1;
188     item = item->next;
189   }
190   return 0;
191 }
192
193 /*
194  * xbt_fifo_to_array()
195  */
196 void **xbt_fifo_to_array(xbt_fifo_t f)
197 {
198   void **array;
199   xbt_fifo_item_t b;
200   int i;
201
202   if (f->count == 0)
203     return NULL;
204   else
205     array = (void **) calloc(f->count, sizeof(void *));
206
207   for (i = 0, b = xbt_fifo_getFirstitem(f); b; i++, b = b->next) {
208     array[i] = b->content;
209   }
210   return array;
211 }
212
213 /*
214  * xbt_fifo_Copy()
215  */
216 xbt_fifo_t xbt_fifo_copy(xbt_fifo_t f)
217 {
218   xbt_fifo_t copy = NULL;
219   xbt_fifo_item_t b;
220
221   copy = xbt_fifo_new();
222
223   for (b = xbt_fifo_getFirstitem(f); b; b = b->next) {
224     xbt_fifo_push(copy, b->content);
225   }
226   return copy;
227 }
228
229 /*
230  * xbt_fifo_newitem()
231  */
232 xbt_fifo_item_t xbt_fifo_newitem(void)
233 {
234   return (xbt_fifo_item_t) calloc(1, sizeof(struct xbt_fifo_item));
235 }
236
237 void xbt_fifo_set_item_content(xbt_fifo_item_t i , void *v)
238 {
239   xbt_fifo_setItemcontent(i,v);
240 }
241
242 void *xbt_fifo_get_item_content(xbt_fifo_item_t i)
243 {
244   return xbt_fifo_getItemcontent(i);
245 }
246
247 /*
248  * xbt_fifo_freeitem()
249  */
250 void xbt_fifo_freeitem(xbt_fifo_item_t b)
251 {
252   free(b);
253   return;
254 }
255
256 int xbt_fifo_size(xbt_fifo_t f)
257 {
258   return f->count;
259 }
260
261