怎样使用 ns 自己的链表
1 .头文件 #include<lib/bsd-list.h>
2 .初始化
1). 在节点中添加,包括了指向前驱和后继的节点。
#define LIST_ENTRY(type)
struct {
type *le_next; /* next element */
type **le_prev; /* address of previous next element */
}
2). 定义一个链表,链表的类型为 type, 表头为 lh_first
#define LIST_HEAD(name, type)
struct name {
type *lh_first; /* first element */
}
3) 初始化链表
#define LIST_INIT(head) {
(head)->lh_first = NULL;
}
4 )插入节点
#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;
}
5 )删除节点
#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; /
}
6 )一个例子
( 1 )定义节点类型
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
};
( 2 )建立一个链表节点类型为 MFlood_RTEntry 的链表 rthead
LIST_HEAD(, MFlood_RTEntry) rthead;
( 3 )初始化链表 rhead 为 NULL
LIST_INIT(& rthead )
(4) 怎样使用
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;
}
( 5 )删除节点
void
MFlood_RTable::rt_delete(nsaddr_t id) {
MFlood_RTEntry *rt = rt_lookup(id);
if(rt) {
LIST_REMOVE(rt, rt_link);
delete rt;
}
}
( 6 )插入节点
rt = new MFlood_RTEntry(ih->saddr(), fh->seq_);
LIST_INSERT_HEAD(&rtable_.rthead,rt,rt_link);
参考:
season的NS技巧13
http://wowseason.spaces.live.com/blog/cns!8A62350BF8613BBF!122.entry