[asterisk-commits] rmudgett: branch rmudgett/ao2_red_black r371780 - /team/rmudgett/ao2_red_blac...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 27 14:32:38 CDT 2012
Author: rmudgett
Date: Mon Aug 27 14:32:34 2012
New Revision: 371780
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371780
Log:
Fix property 5 quick check and add complete property 5 check.
Modified:
team/rmudgett/ao2_red_black/main/astobj2.c
Modified: team/rmudgett/ao2_red_black/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ao2_red_black/main/astobj2.c?view=diff&rev=371780&r1=371779&r2=371780
==============================================================================
--- team/rmudgett/ao2_red_black/main/astobj2.c (original)
+++ team/rmudgett/ao2_red_black/main/astobj2.c Mon Aug 27 14:32:34 2012
@@ -4656,6 +4656,50 @@
#if defined(AST_DEVMODE)
/*!
* \internal
+ * \brief Check the black height of the given node.
+ * \since 12.0.0
+ *
+ * \param node Node to check black height.
+ *
+ * \retval black-height of node on success.
+ * \retval -1 on error. Node black height did not balance.
+ */
+static int rb_check_black_height(struct rbtree_node *node)
+{
+ int height_left;
+ int height_right;
+
+ if (!node) {
+ /* A NULL child is a black node. */
+ return 0;
+ }
+
+ height_left = rb_check_black_height(node->left);
+ if (height_left < 0) {
+ return -1;
+ }
+ height_right = rb_check_black_height(node->right);
+ if (height_right < 0) {
+ return -1;
+ }
+ if (height_left != height_right) {
+ ast_log(LOG_ERROR,
+ "Tree node black height of children does not match! L:%d != R:%d\n",
+ height_left, height_right);
+ return -1;
+ }
+ if (!node->is_red) {
+ /* The node itself is black. */
+ ++height_left;
+ }
+ return height_left;
+}
+
+#endif /* defined(AST_DEVMODE) */
+
+#if defined(AST_DEVMODE)
+/*!
+ * \internal
* \brief Perform an integrity check on the specified container.
* \since 12.0.0
*
@@ -4737,16 +4781,27 @@
}
} else {
/*
- * A black node must have two black children, or two red
- * children, or one red child, or no children.
+ * A black node must have two children, or one red child, or no
+ * children. If the black node has two children and only one of
+ * them is red, that red child must have two children.
*/
if (node->left && node->right) {
/* Node has two children. */
if (node->left->is_red != node->right->is_red) {
- /* Violation rbtree property 5. */
- ast_log(LOG_ERROR,
- "Tree node is black and the left child's color doesn't match the right child!\n");
- res = -1;
+ /* The children are not the same color. */
+ struct rbtree_node *red;
+
+ if (node->left->is_red) {
+ red = node->left;
+ } else {
+ red = node->right;
+ }
+ if (!red->left || !red->right) {
+ /* Violation rbtree property 5. */
+ ast_log(LOG_ERROR,
+ "Tree node is black and the red child does not have two children!\n");
+ res = -1;
+ }
}
} else if ((node->left && !node->left->is_red)
|| (node->right && !node->right->is_red)) {
@@ -4780,6 +4835,12 @@
}
}
obj_last = node->common.obj;
+ }
+
+ /* Completely check property 5 */
+ if (!res && rb_check_black_height(self->root) < 0) {
+ /* Violation rbtree property 5. */
+ res = -1;
}
}
More information about the asterisk-commits
mailing list