1 /*
2 * Wrapper for list.h that keeps track of number of items.
3 *
4 * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /**
20 * @file
21 *
22 * Circular list that keep track of stats about the list.
23 *
24 * Currenly only count of abjects currently in list
25 * is kept track of. The plan was to track more,
26 * like max, but it was not useful enough.
27 */
28 #ifndef _USUAL_STATLIST_H_
29 #define _USUAL_STATLIST_H_
30
31 #include <usual/list.h>
32
33 /**
34 * Header structure for StatList.
35 */
36 struct StatList {
37 /** Actual list head */
38 struct List head;
39 /** Count of objects currently in list */
40 int cur_count;
41 #ifdef LIST_DEBUG
42 /** List name */
43 const char *name;
44 #endif
45 };
46
47 /** Define and initialize StatList head */
48 #ifdef LIST_DEBUG
49 #define STATLIST(var) struct StatList var = { {&var.head, &var.head}, 0, #var }
50 #else
51 #define STATLIST(var) struct StatList var = { {&var.head, &var.head}, 0 }
52 #endif
53
54 /** Add to the start of the list */
statlist_prepend(struct StatList * list,struct List * item)55 static inline void statlist_prepend(struct StatList *list, struct List *item)
56 {
57 list_prepend(&list->head, item);
58 list->cur_count++;
59 }
60
61 /** Add to the end of the list */
statlist_append(struct StatList * list,struct List * item)62 static inline void statlist_append(struct StatList *list, struct List *item)
63 {
64 list_append(&list->head, item);
65 list->cur_count++;
66 }
67
68 /** Remove element from the list */
statlist_remove(struct StatList * list,struct List * item)69 static inline void statlist_remove(struct StatList *list, struct List *item)
70 {
71 list_del(item);
72 list->cur_count--;
73
74 /* Assert(list->cur_count >= 0); */
75 }
76
77 /** Initialize StatList head */
statlist_init(struct StatList * list,const char * name)78 static inline void statlist_init(struct StatList *list, const char *name)
79 {
80 list_init(&list->head);
81 list->cur_count = 0;
82 #ifdef LIST_DEBUG
83 list->name = name;
84 #endif
85 }
86
87 /** return number of elements currently in list */
statlist_count(const struct StatList * list)88 static inline int statlist_count(const struct StatList *list)
89 {
90 /* Assert(list->cur_count > 0 || list_empty(&list->head)); */
91 return list->cur_count;
92 }
93
94 /** remove and return first element */
statlist_pop(struct StatList * list)95 static inline struct List *statlist_pop(struct StatList *list)
96 {
97 struct List *item = list_pop(&list->head);
98
99 if (item)
100 list->cur_count--;
101
102 /* Assert(list->cur_count >= 0); */
103
104 return item;
105 }
106
107 /** Return first element */
statlist_first(const struct StatList * list)108 static inline struct List *statlist_first(const struct StatList *list)
109 {
110 return list_first(&list->head);
111 }
112
113 /** Return last element */
statlist_last(const struct StatList * list)114 static inline struct List *statlist_last(const struct StatList *list)
115 {
116 return list_last(&list->head);
117 }
118
119 /** Is list empty */
statlist_empty(const struct StatList * list)120 static inline bool statlist_empty(const struct StatList *list)
121 {
122 return list_empty(&list->head);
123 }
124
125 /** Loop over list */
126 #define statlist_for_each(item, list) list_for_each(item, &((list)->head))
127
128 /** Loop over list backwards */
129 #define statlist_for_each_reverse(item, list) list_for_each_reverse(item, &((list)->head))
130
131 /** Loop over list safely, so that elements can be removed during */
132 #define statlist_for_each_safe(item, list, tmp) list_for_each_safe(item, &((list)->head), tmp)
133
134 /** Loop over list backwards safely, so that elements can be removed during */
135 #define statlist_for_each_reverse_safe(item, list, tmp) list_for_each_reverse_safe(item, &((list)->head), tmp)
136
137 /** Put intem before another */
statlist_put_before(struct StatList * list,struct List * item,struct List * pos)138 static inline void statlist_put_before(struct StatList *list, struct List *item, struct List *pos)
139 {
140 list_append(pos, item);
141 list->cur_count++;
142 }
143
144 /** Put item after another */
statlist_put_after(struct StatList * list,struct List * item,struct List * pos)145 static inline void statlist_put_after(struct StatList *list, struct List *item, struct List *pos)
146 {
147 list_prepend(pos, item);
148 list->cur_count++;
149 }
150
151 #endif /* __LIST_H_ */
152