首页 > 代码库 > linux内核hash list

linux内核hash list

  1 #ifndef _LINUX_HLIST_H
  2 #define _LINUX_HLIST_H
  3 
  4 /*
  5  * Double linked lists with a single pointer list head.
  6  * Mostly useful for hash tables where the two pointer list head is
  7  * too wasteful.
  8  * You lose the ability to access the tail in O(1).
  9  */
 10 
 11 struct hlist_head {
 12     struct hlist_node *first;
 13 };
 14 
 15 struct hlist_node {
 16     struct hlist_node *next, **pprev;
 17 };
 18 
 19 #ifndef offsetof
 20 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 21 #endif
 22 
 23 #ifndef container_of
 24 /**
 25  * container_of - cast a member of a structure out to the containing structure
 26  * @ptr:    the pointer to the member.
 27  * @type:    the type of the container struct this is embedded in.
 28  * @member:    the name of the member within the struct.
 29  *
 30  */
 31 #define container_of(ptr, type, member) ({             32     const typeof(((type *)0)->member) * __mptr = (ptr);     33     (type *)((char *)__mptr - offsetof(type, member)); })
 34 #endif
 35 
 36 #define HLIST_HEAD_INIT { .first = NULL }
 37 #define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
 38 #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
 39 static inline void INIT_HLIST_NODE(struct hlist_node *h)
 40 {
 41     h->next = NULL;
 42     h->pprev = NULL;
 43 }
 44 
 45 static inline int hlist_unhashed(const struct hlist_node *h)
 46 {
 47     return !h->pprev;
 48 }
 49 
 50 static inline int hlist_empty(const struct hlist_head *h)
 51 {
 52     return !h->first;
 53 }
 54 
 55 static inline void __hlist_del(struct hlist_node *n)
 56 {
 57     struct hlist_node *next = n->next;
 58     struct hlist_node **pprev = n->pprev;
 59     *pprev = next;
 60     if (next)
 61         next->pprev = pprev;
 62 }
 63 
 64 static inline void hlist_del(struct hlist_node *n)
 65 {
 66     __hlist_del(n);
 67     INIT_HLIST_NODE(n);
 68 }
 69 
 70 static inline void hlist_del_init(struct hlist_node *n)
 71 {
 72     if (!hlist_unhashed(n)) {
 73         __hlist_del(n);
 74         INIT_HLIST_NODE(n);
 75     }
 76 }
 77 
 78 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
 79 {
 80     struct hlist_node *first = h->first;
 81     n->next = first;
 82     if (first)
 83         first->pprev = &n->next;
 84     h->first = n;
 85     n->pprev = &h->first;
 86 }
 87 
 88 /* next must be != NULL */
 89 static inline void hlist_add_before(struct hlist_node *n,
 90                     struct hlist_node *next)
 91 {
 92     n->pprev = next->pprev;
 93     n->next = next;
 94     next->pprev = &n->next;
 95     *(n->pprev) = n;
 96 }
 97 
 98 static inline void hlist_add_after(struct hlist_node *n,
 99                     struct hlist_node *next)
100 {
101     next->next = n->next;
102     n->next = next;
103     next->pprev = &n->next;
104 
105     if(next->next)
106         next->next->pprev  = &next->next;
107 }
108 
109 /* after that we‘ll appear to be on some hlist and hlist_del will work */
110 static inline void hlist_add_fake(struct hlist_node *n)
111 {
112     n->pprev = &n->next;
113 }
114 
115 /*
116  * Move a list from one list head to another. Fixup the pprev
117  * reference of the first entry if it exists.
118  */
119 static inline void hlist_move_list(struct hlist_head *old,
120                    struct hlist_head *new)
121 {
122     new->first = old->first;
123     if (new->first)
124         new->first->pprev = &new->first;
125     old->first = NULL;
126 }
127 
128 #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
129 
130 #define hlist_for_each(pos, head) 131     for (pos = (head)->first; pos ; pos = pos->next)
132 
133 #define hlist_for_each_safe(pos, n, head) 134     for (pos = (head)->first; pos && ({ n = pos->next; 1; }); 135          pos = n)
136 
137 /**
138  * hlist_for_each_entry    - iterate over list of given type
139  * @tpos:    the type * to use as a loop cursor.
140  * @pos:    the &struct hlist_node to use as a loop cursor.
141  * @head:    the head for your list.
142  * @member:    the name of the hlist_node within the struct.
143  */
144 #define hlist_for_each_entry(tpos, pos, head, member)             145     for (pos = (head)->first;                     146          pos &&                             147         ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 148          pos = pos->next)
149 
150 /**
151  * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
152  * @tpos:    the type * to use as a loop cursor.
153  * @pos:    the &struct hlist_node to use as a loop cursor.
154  * @member:    the name of the hlist_node within the struct.
155  */
156 #define hlist_for_each_entry_continue(tpos, pos, member)         157     for (pos = (pos)->next;                         158          pos &&                             159         ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 160          pos = pos->next)
161 
162 /**
163  * hlist_for_each_entry_from - iterate over a hlist continuing from current point
164  * @tpos:    the type * to use as a loop cursor.
165  * @pos:    the &struct hlist_node to use as a loop cursor.
166  * @member:    the name of the hlist_node within the struct.
167  */
168 #define hlist_for_each_entry_from(tpos, pos, member)             169     for (; pos &&                             170         ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 171          pos = pos->next)
172 
173 /**
174  * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
175  * @tpos:    the type * to use as a loop cursor.
176  * @pos:    the &struct hlist_node to use as a loop cursor.
177  * @n:        another &struct hlist_node to use as temporary storage
178  * @head:    the head for your list.
179  * @member:    the name of the hlist_node within the struct.
180  */
181 #define hlist_for_each_entry_safe(tpos, pos, n, head, member)          182     for (pos = (head)->first;                     183          pos && ({ n = pos->next; 1; }) &&                  184         ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); 185          pos = n)
186 
187 #endif

 

linux内核hash list