⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rbt.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
}static voiddns_rbt_deletetreeflat(dns_rbt_t *rbt, dns_rbtnode_t **nodep) {	dns_rbtnode_t *parent;	dns_rbtnode_t *node = *nodep;	REQUIRE(VALID_RBT(rbt)); again:	if (node == NULL) {		*nodep = NULL;		return;	} traverse:	if (LEFT(node) != NULL) {		node = LEFT(node);		goto traverse;	}	if (RIGHT(node) != NULL) {		node = RIGHT(node);		goto traverse;	}	if (DOWN(node) != NULL) {		node = DOWN(node);		goto traverse;	}	if (DATA(node) != NULL && rbt->data_deleter != NULL)		rbt->data_deleter(DATA(node), rbt->deleter_arg);	unhash_node(rbt, node);#if DNS_RBT_USEMAGIC	node->magic = 0;#endif	parent = PARENT(node);	if (parent != NULL) {		if (LEFT(parent) == node)			LEFT(parent) = NULL;		else if (DOWN(parent) == node)			DOWN(parent) = NULL;		else if (RIGHT(parent) == node)			RIGHT(parent) = NULL;	}	isc_mem_put(rbt->mctx, node, NODE_SIZE(node));	rbt->nodecount--;	node = parent;	if (rbt->quantum != 0 && --rbt->quantum == 0) {		*nodep = node;		return;	}	goto again;}static voiddns_rbt_indent(int depth) {	int i;	for (i = 0; i < depth; i++)		putchar('\t');}static voiddns_rbt_printnodename(dns_rbtnode_t *node) {	isc_region_t r;	dns_name_t name;	char buffer[DNS_NAME_FORMATSIZE];	dns_offsets_t offsets;	r.length = NAMELEN(node);	r.base = NAME(node);	dns_name_init(&name, offsets);	dns_name_fromregion(&name, &r);	dns_name_format(&name, buffer, sizeof(buffer));	printf("%s", buffer);}static voiddns_rbt_printtree(dns_rbtnode_t *root, dns_rbtnode_t *parent, int depth) {	dns_rbt_indent(depth);	if (root != NULL) {		dns_rbt_printnodename(root);		printf(" (%s", IS_RED(root) ? "RED" : "black");		if (parent) {			printf(" from ");			dns_rbt_printnodename(parent);		}		if ((! IS_ROOT(root) && PARENT(root) != parent) ||		    (  IS_ROOT(root) && depth > 0 &&		       DOWN(PARENT(root)) != root)) {			printf(" (BAD parent pointer! -> ");			if (PARENT(root) != NULL)				dns_rbt_printnodename(PARENT(root));			else				printf("NULL");			printf(")");		}		printf(")\n");		depth++;		if (DOWN(root)) {			dns_rbt_indent(depth);			printf("++ BEG down from ");			dns_rbt_printnodename(root);			printf("\n");			dns_rbt_printtree(DOWN(root), NULL, depth);			dns_rbt_indent(depth);			printf("-- END down from ");			dns_rbt_printnodename(root);			printf("\n");		}		if (IS_RED(root) && IS_RED(LEFT(root)))		    printf("** Red/Red color violation on left\n");		dns_rbt_printtree(LEFT(root), root, depth);		if (IS_RED(root) && IS_RED(RIGHT(root)))		    printf("** Red/Red color violation on right\n");		dns_rbt_printtree(RIGHT(root), root, depth);	} else		printf("NULL\n");}voiddns_rbt_printall(dns_rbt_t *rbt) {	REQUIRE(VALID_RBT(rbt));	dns_rbt_printtree(rbt->root, NULL, 0);}/* * Chain Functions */voiddns_rbtnodechain_init(dns_rbtnodechain_t *chain, isc_mem_t *mctx) {	/*	 * Initialize 'chain'.	 */	REQUIRE(chain != NULL);	chain->mctx = mctx;	chain->end = NULL;	chain->level_count = 0;	chain->level_matches = 0;	chain->magic = CHAIN_MAGIC;}isc_result_tdns_rbtnodechain_current(dns_rbtnodechain_t *chain, dns_name_t *name,			 dns_name_t *origin, dns_rbtnode_t **node){	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(VALID_CHAIN(chain));	if (node != NULL)		*node = chain->end;	if (chain->end == NULL)		return (ISC_R_NOTFOUND);	if (name != NULL) {		NODENAME(chain->end, name);		if (chain->level_count == 0) {			/*			 * Names in the top level tree are all absolute.			 * Always make 'name' relative.			 */			INSIST(dns_name_isabsolute(name));			/*			 * This is cheaper than dns_name_getlabelsequence().			 */			name->labels--;			name->length--;			name->attributes &= ~DNS_NAMEATTR_ABSOLUTE;		}	}	if (origin != NULL) {		if (chain->level_count > 0)			result = chain_name(chain, origin, ISC_FALSE);		else			result = dns_name_copy(dns_rootname, origin, NULL);	}	return (result);}isc_result_tdns_rbtnodechain_prev(dns_rbtnodechain_t *chain, dns_name_t *name,		      dns_name_t *origin){	dns_rbtnode_t *current, *previous, *predecessor;	isc_result_t result = ISC_R_SUCCESS;	isc_boolean_t new_origin = ISC_FALSE;	REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);	predecessor = NULL;	current = chain->end;	if (LEFT(current) != NULL) {		/*		 * Moving left one then right as far as possible is the		 * previous node, at least for this level.		 */		current = LEFT(current);		while (RIGHT(current) != NULL)			current = RIGHT(current);		predecessor = current;	} else {		/*		 * No left links, so move toward the root.  If at any point on		 * the way there the link from parent to child is a right		 * link, then the parent is the previous node, at least		 * for this level.		 */		while (! IS_ROOT(current)) {			previous = current;			current = PARENT(current);			if (RIGHT(current) == previous) {				predecessor = current;				break;			}		}	}	if (predecessor != NULL) {		/*		 * Found a predecessor node in this level.  It might not		 * really be the predecessor, however.		 */		if (DOWN(predecessor) != NULL) {			/*			 * The predecessor is really down at least one level.			 * Go down and as far right as possible, and repeat			 * as long as the rightmost node has a down pointer.			 */			do {				/*				 * XXX DCL Need to do something about origins				 * here. See whether to go down, and if so				 * whether it is truly what Bob calls a				 * new origin.				 */				ADD_LEVEL(chain, predecessor);				predecessor = DOWN(predecessor);				/* XXX DCL duplicated from above; clever				 * way to unduplicate? */				while (RIGHT(predecessor) != NULL)					predecessor = RIGHT(predecessor);			} while (DOWN(predecessor) != NULL);			/* XXX DCL probably needs work on the concept */			if (origin != NULL)				new_origin = ISC_TRUE;		}	} else if (chain->level_count > 0) {		/*		 * Dang, didn't find a predecessor in this level.		 * Got to the root of this level without having traversed		 * any right links.  Ascend the tree one level; the		 * node that points to this tree is the predecessor.		 */		INSIST(chain->level_count > 0 && IS_ROOT(current));		predecessor = chain->levels[--chain->level_count];		/* XXX DCL probably needs work on the concept */		/*		 * Don't declare an origin change when the new origin is "."		 * at the top level tree, because "." is declared as the origin		 * for the second level tree.		 */		if (origin != NULL &&		    (chain->level_count > 0 || OFFSETLEN(predecessor) > 1))			new_origin = ISC_TRUE;	}	if (predecessor != NULL) {		chain->end = predecessor;		if (new_origin) {			result = dns_rbtnodechain_current(chain, name, origin,							  NULL);			if (result == ISC_R_SUCCESS)				result = DNS_R_NEWORIGIN;		} else			result = dns_rbtnodechain_current(chain, name, NULL,							  NULL);	} else		result = ISC_R_NOMORE;	return (result);}isc_result_tdns_rbtnodechain_next(dns_rbtnodechain_t *chain, dns_name_t *name,		      dns_name_t *origin){	dns_rbtnode_t *current, *previous, *successor;	isc_result_t result = ISC_R_SUCCESS;	isc_boolean_t new_origin = ISC_FALSE;	REQUIRE(VALID_CHAIN(chain) && chain->end != NULL);	successor = NULL;	current = chain->end;	/*	 * If there is a level below this node, the next node is the leftmost	 * node of the next level.	 */	if (DOWN(current) != NULL) {		/*		 * Don't declare an origin change when the new origin is "."		 * at the second level tree, because "." is already declared		 * as the origin for the top level tree.		 */		if (chain->level_count > 0 ||		    OFFSETLEN(current) > 1)			new_origin = ISC_TRUE;		ADD_LEVEL(chain, current);		current = DOWN(current);		while (LEFT(current) != NULL)			current = LEFT(current);		successor = current;	} else if (RIGHT(current) == NULL) {		/*		 * The successor is up, either in this level or a previous one.		 * Head back toward the root of the tree, looking for any path		 * that was via a left link; the successor is the node that has		 * that left link.  In the event the root of the level is		 * reached without having traversed any left links, ascend one		 * level and look for either a right link off the point of		 * ascent, or search for a left link upward again, repeating		 * ascents until either case is true.		 */		do {			while (! IS_ROOT(current)) {				previous = current;				current = PARENT(current);				if (LEFT(current) == previous) {					successor = current;					break;				}			}			if (successor == NULL) {				/*				 * Reached the root without having traversed				 * any left pointers, so this level is done.				 */				if (chain->level_count == 0)					break;				current = chain->levels[--chain->level_count];				new_origin = ISC_TRUE;				if (RIGHT(current) != NULL)					break;			}		} while (successor == NULL);	}	if (successor == NULL && RIGHT(current) != NULL) {		current = RIGHT(current);		while (LEFT(current) != NULL)			current = LEFT(current);		successor = current;	}	if (successor != NULL) {		chain->end = successor;		/*		 * It is not necessary to use dns_rbtnodechain_current like		 * the other functions because this function will never		 * find a node in the topmost level.  This is because the		 * root level will never be more than one name, and everything		 * in the megatree is a successor to that node, down at		 * the second level or below.		 */		if (name != NULL)			NODENAME(chain->end, name);		if (new_origin) {			if (origin != NULL)				result = chain_name(chain, origin, ISC_FALSE);			if (result == ISC_R_SUCCESS)				result = DNS_R_NEWORIGIN;		} else			result = ISC_R_SUCCESS;	} else		result = ISC_R_NOMORE;	return (result);}isc_result_tdns_rbtnodechain_first(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,		       dns_name_t *name, dns_name_t *origin){	isc_result_t result;	REQUIRE(VALID_RBT(rbt));	REQUIRE(VALID_CHAIN(chain));	dns_rbtnodechain_reset(chain);	chain->end = rbt->root;	result = dns_rbtnodechain_current(chain, name, origin, NULL);	if (result == ISC_R_SUCCESS)		result = DNS_R_NEWORIGIN;	return (result);}isc_result_tdns_rbtnodechain_last(dns_rbtnodechain_t *chain, dns_rbt_t *rbt,		       dns_name_t *name, dns_name_t *origin){	isc_result_t result;	REQUIRE(VALID_RBT(rbt));	REQUIRE(VALID_CHAIN(chain));	dns_rbtnodechain_reset(chain);	result = move_chain_to_last(chain, rbt->root);	if (result != ISC_R_SUCCESS)		return (result);	result = dns_rbtnodechain_current(chain, name, origin, NULL);	if (result == ISC_R_SUCCESS)		result = DNS_R_NEWORIGIN;	return (result);}voiddns_rbtnodechain_reset(dns_rbtnodechain_t *chain) {	/*	 * Free any dynamic storage associated with 'chain', and then	 * reinitialize 'chain'.	 */	REQUIRE(VALID_CHAIN(chain));	chain->end = NULL;	chain->level_count = 0;	chain->level_matches = 0;}voiddns_rbtnodechain_invalidate(dns_rbtnodechain_t *chain) {	/*	 * Free any dynamic storage associated with 'chain', and then	 * invalidate 'chain'.	 */	dns_rbtnodechain_reset(chain);	chain->magic = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -