这个文件实现了五种数据结构,都是用宏定义来实现。

slist:简单链表

list:结点比简单链表多了一个二级指针

队列的头指针还声明了一个二级指针sqh_last保存队列中最后一个元素的next指针的地址,其目的是:

当我们在队列的尾部插入数据时,就非常方便了,就不必从头指针遍历的最后一个结点,再把要插入的结点的地址复制给最后一个结点的next指针。因为*(head->sqh_last)即表示最后一个结点的next指针。尾部队列的结点比简单队列多了一个二级指针cqe_prev。原因同list。

这应该算作是改进的单链表了。如果非要用container_of宏的经过两次调用的话,也可以当作双链表。
140 #define LIST_HEAD(name, type)                       \
141 struct name {                               \
142     struct type *lh_first;  /* first element */         \
143 }
144 
145 #define LIST_HEAD_INITIALIZER(head)                 \
146     { NULL }
147 
148 #define LIST_ENTRY(type)                        \
149 struct {                                \
150     struct type *le_next;   /* next element */          \
151     struct type **le_prev;  /* address of previous next element */  \
152 }

这种定义方法和我们常用的定义方法他的好处
为什么不这样定义呢?

140 #define LIST_HEAD(name, type)                       \
141 struct name {                               \
142     struct type *lh_first;  /* first element */         \
143 }
144 
145 #define LIST_HEAD_INITIALIZER(head)                 \
146     { NULL }
147 
148 #define LIST_ENTRY(type)                        \
149 struct {                                \
150     struct type *le_next;   /* next element */          \
151     struct type *le_prev;  /* here */ \
152 }


我想了想, 前者定义方法的好处应该是:
插入的时候好使用方便。主要是插入或者删除头部指向的元素时方便,还能保留head的有效性。
比如这个是在元素前面插入时的宏
182 #define LIST_INSERT_BEFORE(listelm, elm, field) do {            \
183     (elm)->field.le_prev = (listelm)->field.le_prev;        \
184     (elm)->field.le_next = (listelm);               \
185     *(listelm)->field.le_prev = (elm);              \
186     (listelm)->field.le_prev = &(elm)->field.le_next;       \
187 } while (0)

这样,即使链表中的listelm就是head->lh_first指向的,那么在插入后,head也会改变。因为first->lh_first->le_prev == &first->lh_first

但如果使用通常情况的双链表定义的话,head->lh_first是没法改变的! 因为没有无法得到指向head->lh_first的指针。而前者有。

在linux内核中struct hlist也是差不多这样定义的。

libevent基础文件compat/sys/queue.h

相关文章:

  • 2021-12-09
  • 2022-12-23
  • 2022-12-23
  • 2021-07-08
  • 2022-12-23
  • 2021-10-22
  • 2021-06-26
  • 2021-05-07
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-06-11
  • 2021-08-28
  • 2021-10-12
  • 2021-08-17
  • 2022-01-09
相关资源
相似解决方案