Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
removed unused variables
[simgrid.git] / src / xbt / fifo.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2004 Arnaud Legrand. All rights reserved.                  */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "xbt/sysdep.h"
9 #include "xbt/log.h"
10 #include "xbt/mallocator.h"
11 #include "fifo_private.h"
12 #include "xbt_modinter.h"
13
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_fifo,xbt,"FIFO");
15
16 static void* fifo_item_mallocator_new_f(void);
17 static void fifo_item_mallocator_free_f(void* item);
18 static void fifo_item_mallocator_reset_f(void* item);
19
20 static xbt_mallocator_t item_mallocator = NULL;
21
22 /** Constructor
23  * \return a new fifo
24  */
25 xbt_fifo_t xbt_fifo_new(void)
26 {
27   xbt_fifo_t fifo;
28   fifo = xbt_new0(struct xbt_fifo,1);
29
30   if (item_mallocator == NULL) {
31     item_mallocator = xbt_mallocator_new(256,
32                                          fifo_item_mallocator_new_f,
33                                          fifo_item_mallocator_free_f,
34                                          fifo_item_mallocator_reset_f);
35   }
36   return fifo;
37 }
38
39 /** Destructor
40  * \param l poor victim
41  *
42  * Free the fifo structure. None of the objects that was in the fifo is however modified.
43  */
44 void xbt_fifo_free(xbt_fifo_t l)
45 {
46   xbt_fifo_item_t b, tmp;
47
48   for (b = xbt_fifo_get_first_item(l); b;
49        tmp = b, b = b->next, xbt_fifo_free_item(tmp));
50   xbt_free(l);
51   return;
52 }
53
54 /** Push
55  * \param l list
56  * \param t element
57  * \return the bucket that was just added
58  *
59  * Add an object at the tail of the list
60  */
61 xbt_fifo_item_t xbt_fifo_push(xbt_fifo_t l, void *t)
62 {
63   xbt_fifo_item_t new;
64
65   new = xbt_fifo_new_item();
66   new->content = t;
67
68   xbt_fifo_push_item(l,new);
69   return new;
70 }
71
72 /** Pop
73  * \param l list
74  * \returns the object stored at the tail of the list.
75  *
76  * Removes and returns the object stored at the tail of the list. 
77  * Returns NULL if the list is empty.
78  */
79 void *xbt_fifo_pop(xbt_fifo_t l)
80 {
81   xbt_fifo_item_t item;
82   void *content;
83
84   if(l==NULL) return NULL;
85   if(!(item = xbt_fifo_pop_item(l))) return NULL;
86
87   content = item->content;
88   xbt_fifo_free_item(item);
89   return content;
90 }
91
92 /**
93  * \param l list
94  * \param t element
95  * \return the bucket that was just added
96  *
97  * Add an object at the head of the list
98  */
99 xbt_fifo_item_t xbt_fifo_unshift(xbt_fifo_t l, void *t)
100 {
101   xbt_fifo_item_t new;
102
103   new = xbt_fifo_new_item();
104   new->content = t;
105   xbt_fifo_unshift_item(l,new);
106   return new;
107 }
108
109 /** Shift
110  * \param l list
111  * \returns the object stored at the head of the list.
112  *
113  * Removes and returns the object stored at the head of the list. 
114  * Returns NULL if the list is empty.
115  */
116 void *xbt_fifo_shift(xbt_fifo_t l)
117 {
118   xbt_fifo_item_t item;
119   void *content;
120
121   if(l==NULL) return NULL;
122   if(!(item = xbt_fifo_shift_item(l))) return NULL;
123   
124   content = item->content;
125   xbt_fifo_free_item(item);
126   return content;
127 }
128
129 /** Push a bucket
130  * \param l list
131  * \param new bucket
132  *
133  * Hook up this bucket at the tail of the list
134  */
135 void xbt_fifo_push_item(xbt_fifo_t l, xbt_fifo_item_t new)
136 {
137   xbt_assert0((new->next == NULL)&&(new->prev == NULL),"Invalid item!");
138   (l->count)++;
139   if (l->head == NULL) {
140     l->head = new;
141     l->tail = new;
142     return;
143   }
144   new->prev = l->tail;
145   new->prev->next = new;
146   l->tail = new;
147 }
148
149 /** Pop bucket
150  * \param l
151  * \returns the bucket that was at the tail of the list.
152  *
153  * Returns NULL if the list was empty.
154  */
155 xbt_fifo_item_t xbt_fifo_pop_item(xbt_fifo_t l)
156 {
157   xbt_fifo_item_t item;
158
159   if (l->tail == NULL)
160     return NULL;
161
162   item = l->tail;
163   
164   l->tail = item->prev;
165   if (l->tail == NULL)
166     l->head = NULL;
167   else
168     l->tail->next = NULL;
169
170   (l->count)--;
171
172   item->prev = NULL;
173
174   return item;
175 }
176
177 /** Push a bucket
178  * \param l list
179  * \param new bucket
180  *
181  * Hook up this bucket at the head of the list
182  */
183 void xbt_fifo_unshift_item(xbt_fifo_t l, xbt_fifo_item_t new)
184 {
185   xbt_assert0((new->next == NULL)&&(new->prev == NULL),"Invalid item!");
186   (l->count)++;
187   if (l->head == NULL) {
188     l->head = new;
189     l->tail = new;
190     return;
191   }
192   new->next = l->head;
193   new->next->prev = new;
194   l->head = new;
195   return;
196 }
197
198 /** Shift bucket
199  * \param l
200  * \returns the bucket that was at the head of the list.
201  *
202  * Returns NULL if the list was empty.
203  */
204 xbt_fifo_item_t xbt_fifo_shift_item(xbt_fifo_t l)
205 {
206   xbt_fifo_item_t item;
207
208   if (l->head == NULL)
209     return NULL;
210
211   item = l->head;
212
213   l->head = item->next;
214   if (l->head == NULL)
215     l->tail = NULL;
216   else
217     l->head->prev = NULL;
218
219   (l->count)--;
220
221   item->next = NULL;
222
223   return item;
224 }
225
226 /**
227  * \param l 
228  * \param t an objet
229  *
230  * removes the first occurence of \a t from \a l. 
231  * \warning it will not remove duplicates
232  * \return 1 if an item was removed and 0 otherwise.
233  */
234 int  xbt_fifo_remove(xbt_fifo_t l, void *t)
235 {
236   xbt_fifo_item_t current, current_next;
237
238
239   for (current = l->head; current; current = current_next) {
240     current_next = current->next;
241     if (current->content != t)
242       continue;
243     /* remove the item */
244     xbt_fifo_remove_item(l, current);
245     xbt_fifo_free_item(current);
246     /* WILL NOT REMOVE DUPLICATES */
247     return 1;
248   }
249   return 0;
250 }
251
252 /**
253  * \param l a list
254  * \param current a bucket
255  *
256  * removes a bucket \a current from the list \a l. This function implicitely 
257  * assumes (and doesn't check!) that this item belongs to this list... 
258  */
259 void xbt_fifo_remove_item(xbt_fifo_t l, xbt_fifo_item_t current)
260 {
261   if (l->head == l->tail) {     /* special case */
262     xbt_assert0((current==l->head),"This item is not in the list!");
263     l->head = NULL;
264     l->tail = NULL;
265     (l->count)--;
266     current->prev = current->next = NULL;
267     return;
268   }
269
270   if (current == l->head) {     /* It's the head */
271     l->head = current->next;
272     l->head->prev = NULL;
273   } else if (current == l->tail) {      /* It's the tail */
274     l->tail = current->prev;
275     l->tail->next = NULL;
276   } else {                      /* It's in the middle */
277     current->prev->next = current->next;
278     current->next->prev = current->prev;
279   }
280   (l->count)--;
281   current->prev = current->next = NULL;
282 }
283
284 /**
285  * \param f a list
286  * \param content an object
287  * \return 1 if \a content is in \a f.
288  */
289 int xbt_fifo_is_in(xbt_fifo_t f, void *content)
290 {
291   xbt_fifo_item_t item = xbt_fifo_get_first_item(f);
292   while (item) {
293     if (item->content == content)
294       return 1;
295     item = item->next;
296   }
297   return 0;
298 }
299
300 /**
301  * \param f a list
302  * \return a table with the objects stored in \a f.
303  */
304 void **xbt_fifo_to_array(xbt_fifo_t f)
305 {
306   void **array;
307   xbt_fifo_item_t b;
308   int i;
309
310   if (f->count == 0)
311     return NULL;
312   else
313     array = xbt_new0(void *, f->count);
314
315   for (i = 0, b = xbt_fifo_get_first_item(f); b; i++, b = b->next) {
316     array[i] = b->content;
317   }
318   return array;
319 }
320
321 /**
322  * \param f a list
323  * \return a copy of \a f.
324  */
325 xbt_fifo_t xbt_fifo_copy(xbt_fifo_t f)
326 {
327   xbt_fifo_t copy = NULL;
328   xbt_fifo_item_t b;
329
330   copy = xbt_fifo_new();
331
332   for (b = xbt_fifo_get_first_item(f); b; b = b->next) {
333     xbt_fifo_push(copy, b->content);
334   }
335   return copy;
336 }
337
338 /* Functions passed to the mallocator constructor */
339 static void* fifo_item_mallocator_new_f(void) {
340   return xbt_new(s_xbt_fifo_item_t, 1);
341 }
342
343 static void fifo_item_mallocator_free_f(void* item) {
344   xbt_free(item);
345 }
346
347 static void fifo_item_mallocator_reset_f(void* item) {
348   /* memset to zero like calloc */
349   memset(item, 0, sizeof(s_xbt_fifo_item_t));
350 }
351
352 /** Constructor
353  * \return a new bucket
354  */
355 xbt_fifo_item_t xbt_fifo_new_item(void)
356 {
357   return xbt_mallocator_get(item_mallocator);
358 }
359
360 /** \deprecated Use #xbt_fifo_new_item instead.
361  */
362 xbt_fifo_item_t xbt_fifo_newitem(void)
363 {
364   WARN0("This function is deprecated. Use xbt_fifo_new_item.");
365   return xbt_fifo_new_item();
366 }
367
368 /**
369  * \param i a bucket
370  * \param v an object
371  *
372  * stores \a v in \a i.
373  */
374 void xbt_fifo_set_item_content(xbt_fifo_item_t i , void *v)
375 {
376   xbt_fifo_setItemcontent(i,v);
377 }
378
379 /**
380  * \param i a bucket
381  * \return the object stored \a i.
382  */
383 void *xbt_fifo_get_item_content(xbt_fifo_item_t i)
384 {
385   return xbt_fifo_getItemcontent(i);
386 }
387
388 /** Destructor
389  * \param b poor victim
390  *
391  * Free the bucket but does not modifies the object (if any) that was stored in it.
392  */
393 void xbt_fifo_free_item(xbt_fifo_item_t b)
394 {
395   xbt_mallocator_release(item_mallocator, b);
396   return;
397 }
398
399 /** Destructor
400  * \deprecated Use #xbt_fifo_free_item instead.
401  */
402 void xbt_fifo_freeitem(xbt_fifo_item_t b)
403 {
404   WARN0("This function is deprecated. Use xbt_fifo_free_item.");
405   xbt_fifo_free_item(b);
406   return;
407 }
408
409 /**
410  * \param f a list
411  * \return the number of buckets in \a f.
412  */
413 int xbt_fifo_size(xbt_fifo_t f)
414 {
415   return f->count;
416 }
417
418 /**
419  * \param l a list
420  * \return the head of \a l.
421  */
422 xbt_fifo_item_t xbt_fifo_get_first_item(xbt_fifo_t l)
423 {
424   return l->head;
425 }
426
427 /** \deprecated Use #xbt_fifo_get_first_item instead.
428  */
429 xbt_fifo_item_t xbt_fifo_getFirstItem(xbt_fifo_t l)
430 {
431   WARN0("This function is deprecated. Use xbt_fifo_get_first_item.");
432   return xbt_fifo_get_first_item(l);
433 }
434
435 /**
436  * \param i a bucket
437  * \return the bucket that comes next
438  */
439 xbt_fifo_item_t xbt_fifo_get_next_item(xbt_fifo_item_t i)
440 {
441   if(i) return i->next;
442   return NULL;
443 }
444
445 /** \deprecated Use #xbt_fifo_get_next_item instead.
446  */
447 xbt_fifo_item_t xbt_fifo_getNextItem(xbt_fifo_item_t i)
448 {
449   WARN0("This function is deprecated. Use xbt_fifo_get_next_item.");
450   return xbt_fifo_get_next_item(i);
451 }
452
453 /**
454  * \param i a bucket
455  * \return the bucket that is just before \a i.
456  */
457 xbt_fifo_item_t xbt_fifo_get_prev_item(xbt_fifo_item_t i)
458 {
459   if(i) return i->prev;
460   return NULL;
461 }
462
463 /** \deprecated Use #xbt_fifo_get_prev_item instead.
464  */
465 xbt_fifo_item_t xbt_fifo_getPrevItem(xbt_fifo_item_t i)
466 {
467   WARN0("This function is deprecated. Use xbt_fifo_get_prev_item.");
468   return xbt_fifo_get_prev_item(i);
469 }
470
471 /**
472  * Destroy the fifo item mallocator.
473  * This is an internal XBT function called by xbt_exit().
474  */
475 void xbt_fifo_exit(void) {
476   if (item_mallocator != NULL) {
477     xbt_mallocator_free(item_mallocator);
478   }
479 }
480
481 /* @} */
482
483