QTAILQ队列数据结构
这种数据结构由两种基本结构构成,分别是QTAILQ_ENTRY和QTAILQ_HEAD,前者表示队列的元素,后者表示队列的头。
#define QTAILQ_ENTRY(type) \
union { \
struct type *tqe_next; /* next element */ \
QTailQLink tqe_circ; /* link for circular backwards list */ \
}
typedef struct QTailQLink {
void *tql_next;
struct QTailQLink *tql_prev;
} QTailQLink;
entry为一个联合体类型,包含tqe_next和tqe_circ,前者适用于单向链表,后者适用于双向链表。
在构造单向链表时,tqe_next指向链表中的下一个元素。
在构造双向链表时,tqe_circ->tql_next指向链表中的下一个元素,tqe_circ->tql_prev指向链表中上一个元素的tqe_circ。
#define QTAILQ_HEAD(name, type) \
union name { \
struct type *tqh_first; /* first element */ \
QTailQLink tqh_circ; /* link for circular backwards list */ \
}
head与entry结构类似,包含tqh_first和tqh_circ,前者适用于单向链表,后者适用于双向链表。
在构造单向链表时,tqh_first指向链表中的第一个元素。
在构造双向链表时,tqh_circ指向链表中的第一个元素的tqh_circ。
基于这些数据结构,有一些操作。
QTAILQ_INSERT_TAIL(head,elm,field)
#define QTAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev; \
(head)->tqh_circ.tql_prev->tql_next = (elm); \
(head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ; \
} while (/*CONSTCOND*/0)
将新元素elm放入整个链表的最后一个。
最后一个元素的下一个元素肯定为NULL,所以(elm)->field.tqe_next = NULL;
最后一个元素的tqe_circ.tql_prev应该指向之前是最后一个元素的元素,即指向(head)->tqh_circ.tql_prev.
之前是最后一个元素的元素,即(head)->tqh_circ.tql_prev,的下一个元素,应该为elm,所以之前的最后一个元素->tql_next = (elm).
head的prev应该是elm,因此(head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ.
QTAILQ_INSERT_AFTER(head, listelm, elm, field)
向队列中的某元素后插入一个新的元素
QTAILQ_INSERT_BEFORE(listelm,elm,field)
向队列中的某元素前插入一个新的元素