NS2의 체인 노트

3119 단어
NS2의 체인 테이블은 bsd-list를 채택했다.h 헤더 파일은 다음과 같습니다.
#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;			\
}
NS에서 체인 테이블을 대량으로 사용했다. 모든 네트워크 노드는 체인 테이블로 꿰맨 다음에 옮겨갈 수 있기 때문이다. 각 노드는 여러 개의 체인 헤드 링크Head와 인터페이스 Phy가 있을 수 있다. (이곳의 노드 Node와 링크Head와Phy의if의 관계는 아직 분명하지 않다) 이런 링크 Head도 체인 테이블로 꿰맨 다음에 네트워크 토폴로지를 형성하는 데 사용한다.그런 다음 라우트를 계산합니다.
모든 type은 체인 원소의 바늘이다. 예를 들어 노드의 체인 시계의 type은 노드의 바늘이고 LinkHead 체인 시계의 type은 LinkHead이다.
LIST_HEAD(name, type)
체인 헤드 구조체를 정의합니다. 구조체만 정의할 뿐 체인 헤드 구조체는 아직 성명하지 않았습니다.
변수, 이것은 클래스의 변수에서 정의해야 합니다.
Node 클래스의 경우 모든 Node 클래스의 인스턴스화된 객체를 체인 테이블로 묶어야 하기 때문에 체인 테이블 헤드는 Node 클래스의 속성에 속하며 그 어떠한 Node 객체의 속성도 아니므로 정적 변수로 정의됩니다.
static struct node_head nodehead_;  // static head of list of nodes
LinkHead의 체인 헤드는 Node 아래의 속성이며 정적 변수로 정의하지 않음
체인 헤드 구조체를 정의하고 체인 헤드 구조체 변수를 정의하며 다음 단계는 체인 헤드 구조체 변수를 초기화하는 것이다. 즉,
#define	LIST_INIT(head)
이것은 단지 체인 헤더에 초기값인 NULL을 부여하는 것일 뿐이다.
여기서 주의해야 할 것은 Node의 체인 헤더 변수는 정적 변수이다. 정적 변수는 클래스에서 성명만 하고 정의도 필요하다. 정의는 실례화하는 과정에서 완성할 수 없고 단독으로 완성해야 한다. 정의와 동시에 초기화한다.
struct node_head Node::nodehead_ = { 0 }; // replaces LIST_INIT macro

LinkHead와if는 노드의 구조 함수에서list의 매크로를 사용하여 직접 초기화할 수 있습니다
LIST_INIT(&ifhead_);
LIST_INIT(&linklisthead_);
#define LIST_ENTRY(type)
ENTRY 테이블 항목 매크로는 클래스에 두 개의 바늘을 추가하여 클래스가 앞뒤로 연결되어 체인 테이블이 될 수 있도록 하는 것이다.
단일 체인 테이블만 사용하기 때문에 삽입된 요소는 Head에서만 삽입됩니다.
마지막으로 Node 클래스에서 두 가지 함수를 정의합니다. 하나는 체인 테이블에 자신을 추가하는 것이고, 하나는 다음 체인 테이블 요소를 되돌려주는 것입니다.
inline void insert(struct node_head* head) {
		LIST_INSERT_HEAD(head, this, entry);
	}
inline Node* nextnode() { return entry.le_next; }

Node의 링크 LinkHead와 인터페이스 Phy if의 관계가 아직 명확하지 않으니 다시 한 번 봐야겠어!

좋은 웹페이지 즐겨찾기