[asterisk-commits] rmudgett: branch rmudgett/ao2_red_black r371658 - /team/rmudgett/ao2_red_blac...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list