Esempio n. 1
0
/************************************************************************
Add a new node to the tree, useful for data that is pre-sorted.
@return	appended node */
UNIV_INTERN
const ib_rbt_node_t*
rbt_add_node(
/*=========*/
	ib_rbt_t*	tree,			/*!< in: rb tree */
	ib_rbt_bound_t*	parent,			/*!< in: bounds */
	const void*	value)			/*!< in: this value is copied
						to the node */
{
	ib_rbt_node_t*	node;

	/* Create the node that will hold the value data */
	node = (ib_rbt_node_t*) ut_malloc(SIZEOF_NODE(tree));

	memcpy(node->value, value, tree->sizeof_value);
	node->parent = node->left = node->right = tree->nil;

	/* If tree is empty */
	if (parent->last == NULL) {
		parent->last = tree->root;
	}

	/* Append the node, the hope here is that the caller knows
	what s/he is doing. */
	rbt_tree_add_child(tree, parent, node);
	rbt_balance_tree(tree, node);

	++tree->n_nodes;

#if	defined(IB_RBT_TESTING)
	ut_a(rbt_validate(tree));
#endif
	return(node);
}
Esempio n. 2
0
/************************************************************************
Generic binary tree insert */
static
ib_rbt_node_t*
rbt_tree_insert(
/*============*/
	ib_rbt_t*	tree,
	const void*	key,
	ib_rbt_node_t*	node)
{
	ib_rbt_bound_t	parent;
	ib_rbt_node_t*	current = ROOT(tree);

	parent.result = 0;
	parent.last = tree->root;

	/* Regular binary search. */
	while (current != tree->nil) {

		parent.last = current;
		parent.result = tree->compare(key, current->value);

		if (parent.result < 0) {
			current = current->left;
		} else {
			current = current->right;
		}
	}

	ut_a(current == tree->nil);

	rbt_tree_add_child(tree, &parent, node);

	return(node);
}
Esempio n. 3
0
/****************************************************************//**
Add a new caller-provided node to tree at the specified position.
The node must have its key fields initialized correctly.
@return added node */
UNIV_INTERN
const ib_rbt_node_t*
rbt_add_preallocated_node(
/*======================*/
	ib_rbt_t*	tree,			/*!< in: rb tree */
	ib_rbt_bound_t*	parent,			/*!< in: parent */
	ib_rbt_node_t*	node)			/*!< in: node */
{
	node->parent = node->left = node->right = tree->nil;

	/* If tree is empty */
	if (parent->last == NULL) {
		parent->last = tree->root;
	}

	/* Append the node, the hope here is that the caller knows
	   what s/he is doing. */
	rbt_tree_add_child(tree, parent, node);
	rbt_balance_tree(tree, node);

	++tree->n_nodes;

#if	defined(IB_RBT_TESTING)
	ut_a(rbt_validate(tree));
#endif
	return(node);
}
Esempio n. 4
0
/************************************************************************
Merge the node from dst into src. Return the number of nodes merged.
Delete the nodes from src after copying node to dst. As a side effect
the duplicates will be left untouched in the src.
@return	no. of recs merged */
UNIV_INTERN
ulint
rbt_merge_uniq_destructive(
/*=======================*/
	ib_rbt_t*	dst,			/*!< in: dst rb tree */
	ib_rbt_t*	src)			/*!< in: src rb tree */
{
	ib_rbt_bound_t	parent;
	ib_rbt_node_t*	src_node;
	ulint		old_size = rbt_size(dst);

	if (rbt_empty(src) || dst == src) {
		return(0);
	}

	for (src_node = (ib_rbt_node_t*) rbt_first(src); src_node; /* */) {
		ib_rbt_node_t*	prev = src_node;

		src_node = (ib_rbt_node_t*)rbt_next(src, prev);

		/* Skip duplicates. */
		if (rbt_search(dst, &parent, prev->value) != 0) {

			/* Remove and reset the node but preserve
			the node (data) value. */
			rbt_remove_node_and_rebalance(src, prev);

			/* The nil should be taken from the dst tree. */
			prev->parent = prev->left = prev->right = dst->nil;
			rbt_tree_add_child(dst, &parent, prev);
			rbt_balance_tree(dst, prev);

			++dst->n_nodes;
		}
	}

#if	defined(IB_RBT_TESTING)
	ut_a(rbt_validate(dst));
	ut_a(rbt_validate(src));
#endif
	return(rbt_size(dst) - old_size);
}