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

📄 rbt.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 5 页
字号:
		node = oldtable[i];		while (node != NULL) {			hash = HASHVAL(node) % rbt->hashsize;			oldtable[i] = HASHNEXT(node);			HASHNEXT(node) = rbt->hashtable[hash];			rbt->hashtable[hash] = node;			node = oldtable[i];		}	}	isc_mem_put(rbt->mctx, oldtable, oldsize * sizeof(dns_rbtnode_t *));}static inline voidhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) {	REQUIRE(DNS_RBTNODE_VALID(node));	if (rbt->nodecount >= (rbt->hashsize *3))		rehash(rbt);	hash_add_node(rbt, node);}static inline voidunhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) {	unsigned int bucket;	dns_rbtnode_t *bucket_node;	REQUIRE(DNS_RBTNODE_VALID(node));	if (rbt->hashtable != NULL) {		bucket = HASHVAL(node) % rbt->hashsize;		bucket_node = rbt->hashtable[bucket];		if (bucket_node == node)			rbt->hashtable[bucket] = HASHNEXT(node);		else {			while (HASHNEXT(bucket_node) != node) {				INSIST(HASHNEXT(bucket_node) != NULL);				bucket_node = HASHNEXT(bucket_node);			}			HASHNEXT(bucket_node) = HASHNEXT(node);		}	}}#endif /* DNS_RBT_USEHASH */static inline voidrotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp) {	dns_rbtnode_t *child;	REQUIRE(DNS_RBTNODE_VALID(node));	REQUIRE(rootp != NULL);	child = RIGHT(node);	INSIST(child != NULL);	RIGHT(node) = LEFT(child);	if (LEFT(child) != NULL)		PARENT(LEFT(child)) = node;	LEFT(child) = node;	if (child != NULL)		PARENT(child) = PARENT(node);	if (IS_ROOT(node)) {		*rootp = child;		child->is_root = 1;		node->is_root = 0;	} else {		if (LEFT(PARENT(node)) == node)			LEFT(PARENT(node)) = child;		else			RIGHT(PARENT(node)) = child;	}	PARENT(node) = child;}static inline voidrotate_right(dns_rbtnode_t *node, dns_rbtnode_t **rootp) {	dns_rbtnode_t *child;	REQUIRE(DNS_RBTNODE_VALID(node));	REQUIRE(rootp != NULL);	child = LEFT(node);	INSIST(child != NULL);	LEFT(node) = RIGHT(child);	if (RIGHT(child) != NULL)		PARENT(RIGHT(child)) = node;	RIGHT(child) = node;	if (child != NULL)		PARENT(child) = PARENT(node);	if (IS_ROOT(node)) {		*rootp = child;		child->is_root = 1;		node->is_root = 0;	} else {		if (LEFT(PARENT(node)) == node)			LEFT(PARENT(node)) = child;		else			RIGHT(PARENT(node)) = child;	}	PARENT(node) = child;}/* * This is the real workhorse of the insertion code, because it does the * true red/black tree on a single level. */static voiddns_rbt_addonlevel(dns_rbtnode_t *node, dns_rbtnode_t *current, int order, 		   dns_rbtnode_t **rootp){	dns_rbtnode_t *child, *root, *parent, *grandparent;	dns_name_t add_name, current_name;	dns_offsets_t add_offsets, current_offsets;	REQUIRE(rootp != NULL);	REQUIRE(DNS_RBTNODE_VALID(node) && LEFT(node) == NULL &&		RIGHT(node) == NULL);	REQUIRE(current != NULL);	root = *rootp;	if (root == NULL) {		/*		 * First node of a level.		 */		MAKE_BLACK(node);		node->is_root = 1;		PARENT(node) = current;		*rootp = node;		return;	}	child = root;	dns_name_init(&add_name, add_offsets);	NODENAME(node, &add_name);	dns_name_init(&current_name, current_offsets);	NODENAME(current, &current_name);	if (order < 0) {		INSIST(LEFT(current) == NULL);		LEFT(current) = node;	} else {		INSIST(RIGHT(current) == NULL);		RIGHT(current) = node;	}	INSIST(PARENT(node) == NULL);	PARENT(node) = current;	MAKE_RED(node);	while (node != root && IS_RED(PARENT(node))) {		/*		 * XXXDCL could do away with separate parent and grandparent		 * variables.  They are vestiges of the days before parent		 * pointers.  However, they make the code a little clearer.		 */		parent = PARENT(node);		grandparent = PARENT(parent);		if (parent == LEFT(grandparent)) {			child = RIGHT(grandparent);			if (child != NULL && IS_RED(child)) {				MAKE_BLACK(parent);				MAKE_BLACK(child);				MAKE_RED(grandparent);				node = grandparent;			} else {				if (node == RIGHT(parent)) {					rotate_left(parent, &root);					node = parent;					parent = PARENT(node);					grandparent = PARENT(parent);				}				MAKE_BLACK(parent);				MAKE_RED(grandparent);				rotate_right(grandparent, &root);			}		} else {			child = LEFT(grandparent);			if (child != NULL && IS_RED(child)) {				MAKE_BLACK(parent);				MAKE_BLACK(child);				MAKE_RED(grandparent);				node = grandparent;			} else {				if (node == LEFT(parent)) {					rotate_right(parent, &root);					node = parent;					parent = PARENT(node);					grandparent = PARENT(parent);				}				MAKE_BLACK(parent);				MAKE_RED(grandparent);				rotate_left(grandparent, &root);			}		}	}	MAKE_BLACK(root);	ENSURE(IS_ROOT(root));	*rootp = root;	return;}/* * This is the real workhorse of the deletion code, because it does the * true red/black tree on a single level. */static voiddns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) {	dns_rbtnode_t *child, *sibling, *parent;	dns_rbtnode_t *successor;	REQUIRE(delete != NULL);	/*	 * Verify that the parent history is (apparently) correct.	 */	INSIST((IS_ROOT(delete) && *rootp == delete) ||	       (! IS_ROOT(delete) &&		(LEFT(PARENT(delete)) == delete ||		 RIGHT(PARENT(delete)) == delete)));	child = NULL;	if (LEFT(delete) == NULL) {		if (RIGHT(delete) == NULL) {			if (IS_ROOT(delete)) {				/*				 * This is the only item in the tree.				 */				*rootp = NULL;				return;			}		} else			/*			 * This node has one child, on the right.			 */			child = RIGHT(delete);	} else if (RIGHT(delete) == NULL)		/*		 * This node has one child, on the left.		 */		child = LEFT(delete);	else {		dns_rbtnode_t holder, *tmp = &holder;		/*		 * This node has two children, so it cannot be directly		 * deleted.  Find its immediate in-order successor and		 * move it to this location, then do the deletion at the		 * old site of the successor.		 */		successor = RIGHT(delete);		while (LEFT(successor) != NULL)			successor = LEFT(successor);		/*		 * The successor cannot possibly have a left child;		 * if there is any child, it is on the right.		 */		if (RIGHT(successor) != NULL)			child = RIGHT(successor);		/*		 * Swap the two nodes; it would be simpler to just replace		 * the value being deleted with that of the successor,		 * but this rigamarole is done so the caller has complete		 * control over the pointers (and memory allocation) of		 * all of nodes.  If just the key value were removed from		 * the tree, the pointer to the node would be unchanged.		 */		/*		 * First, put the successor in the tree location of the		 * node to be deleted.  Save its existing tree pointer		 * information, which will be needed when linking up		 * delete to the successor's old location.		 */		memcpy(tmp, successor, sizeof(dns_rbtnode_t));		if (IS_ROOT(delete)) {			*rootp = successor;			successor->is_root = ISC_TRUE;			delete->is_root = ISC_FALSE;		} else			if (LEFT(PARENT(delete)) == delete)				LEFT(PARENT(delete)) = successor;			else				RIGHT(PARENT(delete)) = successor;		PARENT(successor) = PARENT(delete);		LEFT(successor)   = LEFT(delete);		RIGHT(successor)  = RIGHT(delete);		COLOR(successor)  = COLOR(delete);		if (LEFT(successor) != NULL)			PARENT(LEFT(successor)) = successor;		if (RIGHT(successor) != successor)			PARENT(RIGHT(successor)) = successor;		/*		 * Now relink the node to be deleted into the		 * successor's previous tree location.  PARENT(tmp)		 * is the successor's original parent.		 */		INSIST(! IS_ROOT(delete));		if (PARENT(tmp) == delete) {			/*			 * Node being deleted was successor's parent.			 */			RIGHT(successor) = delete;			PARENT(delete) = successor;		} else {			LEFT(PARENT(tmp)) = delete;			PARENT(delete) = PARENT(tmp);		}		/*		 * Original location of successor node has no left.		 */		LEFT(delete)   = NULL;		RIGHT(delete)  = RIGHT(tmp);		COLOR(delete)  = COLOR(tmp);	}	/*	 * Remove the node by removing the links from its parent.	 */	if (! IS_ROOT(delete)) {		if (LEFT(PARENT(delete)) == delete)			LEFT(PARENT(delete)) = child;		else			RIGHT(PARENT(delete)) = child;		if (child != NULL)			PARENT(child) = PARENT(delete);	} else {		/*		 * This is the root being deleted, and at this point		 * it is known to have just one child.		 */		*rootp = child;		child->is_root = 1;		PARENT(child) = PARENT(delete);	}	/*	 * Fix color violations.	 */	if (IS_BLACK(delete)) {		parent = PARENT(delete);		while (child != *rootp && IS_BLACK(child)) {			INSIST(child == NULL || ! IS_ROOT(child));			if (LEFT(parent) == child) {				sibling = RIGHT(parent);				if (IS_RED(sibling)) {					MAKE_BLACK(sibling);					MAKE_RED(parent);					rotate_left(parent, rootp);					sibling = RIGHT(parent);				}				if (IS_BLACK(LEFT(sibling)) &&				    IS_BLACK(RIGHT(sibling))) {					MAKE_RED(sibling);					child = parent;				} else {					if (IS_BLACK(RIGHT(sibling))) {						MAKE_BLACK(LEFT(sibling));						MAKE_RED(sibling);						rotate_right(sibling, rootp);						sibling = RIGHT(parent);					}					COLOR(sibling) = COLOR(parent);					MAKE_BLACK(parent);					MAKE_BLACK(RIGHT(sibling));					rotate_left(parent, rootp);					child = *rootp;				}			} else {				/*				 * Child is parent's right child.				 * Everything is doen the same as above,				 * except mirrored.				 */				sibling = LEFT(parent);				if (IS_RED(sibling)) {					MAKE_BLACK(sibling);					MAKE_RED(parent);					rotate_right(parent, rootp);					sibling = LEFT(parent);				}				if (IS_BLACK(LEFT(sibling)) &&				    IS_BLACK(RIGHT(sibling))) {					MAKE_RED(sibling);					child = parent;				} else {					if (IS_BLACK(LEFT(sibling))) {						MAKE_BLACK(RIGHT(sibling));						MAKE_RED(sibling);						rotate_left(sibling, rootp);						sibling = LEFT(parent);					}					COLOR(sibling) = COLOR(parent);					MAKE_BLACK(parent);					MAKE_BLACK(LEFT(sibling));					rotate_right(parent, rootp);					child = *rootp;				}			}			parent = PARENT(child);		}		if (IS_RED(child))			MAKE_BLACK(child);	}}/* * This should only be used on the root of a tree, because no color fixup * is done at all. * * NOTE: No root pointer maintenance is done, because the function is only * used for two cases: * + deleting everything DOWN from a node that is itself being deleted, and * + deleting the entire tree of trees from dns_rbt_destroy. * In each case, the root pointer is no longer relevant, so there * is no need for a root parameter to this function. * * If the function is ever intended to be used to delete something where * a pointer needs to be told that this tree no longer exists, * this function would need to adjusted accordingly. */static isc_result_tdns_rbt_deletetree(dns_rbt_t *rbt, dns_rbtnode_t *node) {	isc_result_t result = ISC_R_SUCCESS;	REQUIRE(VALID_RBT(rbt));	if (node == NULL)		return (result);	if (LEFT(node) != NULL) {		result = dns_rbt_deletetree(rbt, LEFT(node));		if (result != ISC_R_SUCCESS)			goto done;		LEFT(node) = NULL;	}	if (RIGHT(node) != NULL) {		result = dns_rbt_deletetree(rbt, RIGHT(node));		if (result != ISC_R_SUCCESS)			goto done;		RIGHT(node) = NULL;	}	if (DOWN(node) != NULL) {		result = dns_rbt_deletetree(rbt, DOWN(node));		if (result != ISC_R_SUCCESS)			goto done;		DOWN(node) = NULL;	} done:	if (result != ISC_R_SUCCESS)		return (result);	if (rbt->quantum != 0 && --rbt->quantum == 0)		return (ISC_R_QUOTA);	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	isc_mem_put(rbt->mctx, node, NODE_SIZE(node));	rbt->nodecount--;	return (result);

⌨️ 快捷键说明

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