[svn-commits] rmudgett: branch rmudgett/ao2_red_black r371658 - /team/rmudgett/ao2_red_blac...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 24 16:57:34 CDT 2012


Author: rmudgett
Date: Fri Aug 24 16:57:30 2012
New Revision: 371658

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371658
Log:
Check rbtree color integrity.

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=371658&r1=371657&r2=371658
==============================================================================
--- team/rmudgett/ao2_red_black/main/astobj2.c (original)
+++ team/rmudgett/ao2_red_black/main/astobj2.c Fri Aug 24 16:57:30 2012
@@ -4400,8 +4400,6 @@
  */
 static int rb_ao2_integrity(struct ao2_container_rbtree *self)
 {
-/* BUGBUG rb_ao2_integrity not written */
-
 	int count_node;
 	int count_obj;
 	void *obj_last;
@@ -4410,21 +4408,75 @@
 	count_node = 0;
 	count_obj = 0;
 
+	/*
+	 * See the properties listed at struct rbtree_node definition.
+	 *
+	 * The rbtree properties 1 and 3 are not testable.
+	 *
+	 * Property 1 is not testable because we are not rebalancing at
+	 * this time so all nodes are either red or black.
+	 *
+	 * Property 3 is not testable because it is the definition of a
+	 * NULL child.
+	 */
 	if (self->root) {
 		/* Check tree links. */
 		if (self->root->parent) {
-			ast_log(LOG_ERROR, "Red-black tree root is not a root node!\n");
+			ast_log(LOG_ERROR, "Tree root is not a root node!\n");
 			return -1;
+		}
+		if (self->root->is_red) {
+			/* Violation rbtree property 2. */
+			ast_log(LOG_ERROR, "Tree root is red!\n");
 		}
 		node = self->root;
 		do {
 			if (node->left && node->left->parent != node) {
-				ast_log(LOG_ERROR, "Red-black tree node's left child does not link back!\n");
+				ast_log(LOG_ERROR, "Tree node's left child does not link back!\n");
 				return -1;
 			}
 			if (node->right && node->right->parent != node) {
-				ast_log(LOG_ERROR, "Red-black tree node's right child does not link back!\n");
+				ast_log(LOG_ERROR, "Tree node's right child does not link back!\n");
 				return -1;
+			}
+
+			/* Check red/black node flags. */
+			if (node->is_red) {
+				/* A red node must have two black children or no children. */
+				if (node->left && node->right) {
+					/* Node has two children. */
+					if (node->left->is_red) {
+						/* Violation rbtree property 4. */
+						ast_log(LOG_ERROR, "Tree node is red and its left child is red!\n");
+					}
+					if (node->right->is_red) {
+						/* Violation rbtree property 4. */
+						ast_log(LOG_ERROR, "Tree node is red and its right child is red!\n");
+					}
+				} else if (node->left || node->right) {
+					/*
+					 * Violation rbtree property 4 if the child is red.
+					 * Violation rbtree property 5 if the child is black.
+					 */
+					ast_log(LOG_ERROR, "Tree node is red and it only has one child!\n");
+				}
+			} else {
+				/*
+				 * A black node must have two black children, or two red
+				 * children, or one red child, or no 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");
+					}
+				} else if ((node->left && !node->left->is_red)
+					|| (node->right && !node->right->is_red)) {
+					/* Violation rbtree property 5. */
+					ast_log(LOG_ERROR, "Tree node is black and its only child is black!\n");
+				}
 			}
 
 			/* Count nodes and objects. */
@@ -4436,7 +4488,7 @@
 			node = rb_node_pre(node);
 		} while (node);
 
-		/* Check forward list. */
+		/* Check node key sort order. */
 		obj_last = NULL;
 		for (node = rb_node_most_left(self->root); node; node = rb_node_next(node)) {
 			if (!node->common.obj) {
@@ -4444,21 +4496,13 @@
 				continue;
 			}
 
-			/* Check sort order. */
 			if (obj_last) {
 				if (self->common.sort_fn(obj_last, node->common.obj, OBJ_POINTER) > 0) {
-					ast_log(LOG_ERROR, "Red-black tree nodes out of sorted order!\n");
+					ast_log(LOG_ERROR, "Tree nodes are out of sorted order!\n");
 					return -1;
 				}
 			}
 			obj_last = node->common.obj;
-		}
-
-/* BUGBUG Check red/black node flags. */
-		/* Check red/black node flags. */
-		if (self->root->is_red) {
-			ast_log(LOG_ERROR, "Red-black tree root is red!\n");
-			return -1;
 		}
 	}
 




More information about the svn-commits mailing list