[svn-commits] rmudgett: branch rmudgett/ao2_red_black r371817 - in /team/rmudgett/ao2_red_b...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Aug 27 18:02:02 CDT 2012


Author: rmudgett
Date: Mon Aug 27 18:01:59 2012
New Revision: 371817

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371817
Log:
Fix rbtree OBJ_CONTINUE handling if the search key is not in the tree.

Modified:
    team/rmudgett/ao2_red_black/include/asterisk/astobj2.h
    team/rmudgett/ao2_red_black/main/astobj2.c

Modified: team/rmudgett/ao2_red_black/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ao2_red_black/include/asterisk/astobj2.h?view=diff&rev=371817&r1=371816&r2=371817
==============================================================================
--- team/rmudgett/ao2_red_black/include/asterisk/astobj2.h (original)
+++ team/rmudgett/ao2_red_black/include/asterisk/astobj2.h Mon Aug 27 18:01:59 2012
@@ -868,6 +868,10 @@
 	 * keep searching through the rest of the buckets if a match is
 	 * not found in the starting bucket defined by the hash value on
 	 * the argument.
+	 *
+	 * For rbtree containers, if the search key is not in the
+	 * container, the search will start either at the first item
+	 * before the search key or the first item after the search key.
 	 *
 	 * \note The supplied ao2_callback_fn is called for every node
 	 * in the container from the starting point.

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=371817&r1=371816&r2=371817
==============================================================================
--- team/rmudgett/ao2_red_black/main/astobj2.c (original)
+++ team/rmudgett/ao2_red_black/main/astobj2.c Mon Aug 27 18:01:59 2012
@@ -4307,6 +4307,7 @@
  *   OBJ_POINTER - if set, 'obj_right', is an object.
  *   OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.
  *   OBJ_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
+ *   OBJ_CONTINUE - if set, return node right before or right after search key if not a match.
  *
  * \retval node on success.
  * \retval NULL if not found.
@@ -4314,33 +4315,56 @@
 static struct rbtree_node *rb_find_initial(struct ao2_container_rbtree *self, void *obj_right, enum search_flags flags)
 {
 	int cmp;
+	enum search_flags sort_flags;
 	struct rbtree_node *node;
+	struct rbtree_node *next;
 	ao2_sort_fn *sort_fn;
 
+	sort_flags = flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY);
 	sort_fn = self->common.sort_fn;
 
 	/* Find node where normal search would find it. */
 	node = self->root;
-	while (node) {
+	if (!node) {
+		return NULL;
+	}
+	for (;;) {
 		if (!node->common.obj) {
 			/* Which direction do we go to find the node? */
-			if (rb_find_empty_direction(node, sort_fn, obj_right, flags)) {
-				node = node->left;
+			if (rb_find_empty_direction(node, sort_fn, obj_right, sort_flags)) {
+				next = node->left;
 			} else {
-				node = node->right;
+				next = node->right;
+			}
+			if (!next) {
+				/* No match found. */
+				if (flags & OBJ_CONTINUE) {
+					next = rb_node_next_full(node);
+					if (!next) {
+						next = rb_node_prev_full(node);
+					}
+				}
+				return next;
 			}
 		} else {
-			cmp = sort_fn(node->common.obj, obj_right, flags);
+			cmp = sort_fn(node->common.obj, obj_right, sort_flags);
 			if (cmp > 0) {
-				node = node->left;
+				next = node->left;
 			} else if (cmp < 0) {
-				node = node->right;
+				next = node->right;
 			} else {
-				break;
-			}
-		}
-	}
-	return node;
+				return node;
+			}
+			if (!next) {
+				/* No match found. */
+				if (flags & OBJ_CONTINUE) {
+					return node;
+				}
+				return NULL;
+			}
+		}
+		node = next;
+	}
 }
 
 /*!
@@ -4401,8 +4425,7 @@
 		}
 
 		/* Search for initial node. */
-		node = rb_find_initial(self, arg,
-			flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY));
+		node = rb_find_initial(self, arg, flags);
 		if (!node) {
 			return NULL;
 		}
@@ -4444,8 +4467,7 @@
 		}
 
 		/* Search for initial node. */
-		node = rb_find_initial(self, arg,
-			flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY));
+		node = rb_find_initial(self, arg, flags);
 		if (!node) {
 			return NULL;
 		}




More information about the svn-commits mailing list