ns2中链表的定义在/ns-allinone-2.35/ns2.35/lib/bsd-list.h中。
学习的协议为AOMDV,链表的具体使用在aomdv.h中。
-----------------------------------------------------------链表的定义-----------------------------------------------------------
List的定义:
#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 */ \ }
使用结构体定义链表,参数name规定了链表明,type定义了元素的类型。LIST_ENTRY中的成员le_prev,它不是平时双向链表中的前向指针(指向前一个元素),而是前向前一个元素的le_next成员的指针。le_prev指向的是指针的地址,而不是元素的地址。
aomdv.h中的class AOMDV_Route定义了构造函数:
AOMDV_Route(nsaddr_t nexthop, nsaddr_t lasthop=0) { nh_addr = nexthop; lh_addr = lasthop; }
之后使用LIST_ENTRY和LIST_HEAD构造了链表元素route_link,链表头为aomdv_routes:
LIST_ENTRY(AOMDV_Route) route_link; LIST_HEAD(aomdv_routes, AOMDV_Route);
List Function:
#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; \ }
aomdv_routes reverse_path_list; // List of reverse paths used for forwarding replies
aomdv_routes forward_path_list; // List of forward paths advertised already
在类AOMDVBroadcastID的构造函数中初始化链表:
AOMDVBroadcastID(nsaddr_t i, u_int32_t b) { src = i; id = b; // AOMDV code count=0; LIST_INIT(&reverse_path_list); LIST_INIT(&forward_path_list); }
在类AOMDVBroadcastID的成员函数reverse_path_insert()中将元素插入链表中。(前向链表类似)
inline AOMDV_Route* reverse_path_insert(nsaddr_t nexthop, nsaddr_t lasthop=0) { AOMDV_Route* route = new AOMDV_Route(nexthop, lasthop); assert(route); LIST_INSERT_HEAD(&reverse_path_list, route, route_link); return route; }
链表的遍历:
inline AOMDV_Route* reverse_path_lookup(nsaddr_t nexthop, nsaddr_t lasthop=0) { AOMDV_Route *route = reverse_path_list.lh_first; // Search the list for a match of id for( ; route; route = route->route_link.le_next) { if ( (route->nh_addr == nexthop) && (route->lh_addr == lasthop) ) return route; } return NULL; }