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