#define LIST_INSERT_AFTER(listelm, elm, field) { if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) (listelm)->field.le_next->field.le_prev = &(elm)->field.le_next; (listelm)->field.le_next = (elm); (elm)->field.le_prev = &(listelm)->field.le_next; } #define LIST_INSERT_BEFORE(listelm, elm, field) { (elm)->field.le_prev = (listelm)->field.le_prev; (elm)->field.le_next = (listelm); *(listelm)->field.le_prev = (elm); (listelm)->field.le_prev = &(elm)->field.le_next; } #define LIST_INSERT_HEAD(head, elm, field) { if (((elm)->field.le_next = (head)->lh_first) != NULL) (head)->lh_first->field.le_prev = &(elm)->field.le_next; (head)->lh_first = (elm); (elm)->field.le_prev = &(head)->lh_first; }
class MFlood_RTEntry { friend class MFlood_RTable; friend class MFlood; public: MFlood_RTEntry(); MFlood_RTEntry(nsaddr_t src,u_int32_t seq); bool isNewSeq(u_int32_t seq); // old -> false, new->true void addSeq(u_int32_t seq); // add a seqno to seqno array(rt_seqnos) protected: LIST_ENTRY(MFlood_RTEntry) rt_link; nsaddr_t src_; // u_int32_t seq_; u_int32_t rt_seqnos[REM_SEQ_COUNT]; //seqno array u_int32_t max_seqno; //max seqno u_int32_t min_seqno; //max seqno u_int16_t seq_it; // seqno's iterator };
MFlood_RTEntry* MFlood_Rtable::rt_lookup(nsaddr_t id) { Mflood_RTEntry *rt = rthead.lh_first;//获取链表表头 for(; rt; rt = rt->rt_link.le_next) { if(rt->src_ == id) break; } return rt; }
双链表示意图:
#define LIST_HEAD(name, type) \ struct name { \ type *lh_first; /* first element */ \ } #define LIST_ENTRY(type) \ struct { \ type *le_next; /* next element */ \ type **le_prev; /* address of previous next element */ \ } /* * List functions. */ #define LIST_INIT(head) { \ (head)->lh_first = NULL; \ } #define LIST_INSERT_AFTER(listelm, elm, field) { \ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ (listelm)->field.le_next->field.le_prev = \ &(elm)->field.le_next; \ (listelm)->field.le_next = (elm); \ (elm)->field.le_prev = &(listelm)->field.le_next; \ } #define LIST_INSERT_BEFORE(listelm, elm, field) { \ (elm)->field.le_prev = (listelm)->field.le_prev; \ (elm)->field.le_next = (listelm); \ *(listelm)->field.le_prev = (elm); \ (listelm)->field.le_prev = &(elm)->field.le_next; \ } #define LIST_INSERT_HEAD(head, elm, field) { \ if (((elm)->field.le_next = (head)->lh_first) != NULL) \ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ (head)->lh_first = (elm); \ (elm)->field.le_prev = &(head)->lh_first; \ } #define LIST_REMOVE(elm, field) { \ if ((elm)->field.le_next != NULL) \ (elm)->field.le_next->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = (elm)->field.le_next; \ }
//此例创建了一个链表,名为rt_path_list, 该链表中的元素类型为AODV_path class AODV_Path { … public: … protected: LIST_ENTRY(AODV_Path) path_link;// path_link相当与field … }; LIST_HEAD(aodv_paths, AODV_Path);//定义结构体 aodv_paths rt_path_list;// rt_path_list相当与源代码中的head //初始化 LIST_INIT(&rt_path_list); //在path后插入p元素(原文:在p元素后插入path元素,似有误!) LIST_INSERT_AFTER(p, path, path_link); //在表头插入path LIST_INSERT_HEAD(&rt_path_list, path, path_link); //将path从链表中删除 LIST_REMOVE(path, path_link); //获取链表表头元素 AODV_Path *path = rt_path_list.lh_first;