diff --git a/include/ofi_tree.h b/include/ofi_tree.h index a2efbf622ad..1d11a5e48f9 100644 --- a/include/ofi_tree.h +++ b/include/ofi_tree.h @@ -80,6 +80,10 @@ ofi_rbmap_create(int (*compare)(struct ofi_rbmap *map, void *key, void *data)); void ofi_rbmap_destroy(struct ofi_rbmap *map); void ofi_rbmap_init(struct ofi_rbmap *map, int (*compare)(struct ofi_rbmap *map, void *key, void *data)); +typedef int (*ofi_rbmap_node_func_t)(struct ofi_rbmap *map, + struct ofi_rbnode *node, void *context); +int ofi_rbmap_foreach(struct ofi_rbmap *map, struct ofi_rbnode *root, + ofi_rbmap_node_func_t func, void *context); void ofi_rbmap_cleanup(struct ofi_rbmap *map); struct ofi_rbnode *ofi_rbmap_get_root(struct ofi_rbmap *map); diff --git a/src/tree.c b/src/tree.c index 7419bd744d9..c66d3662441 100644 --- a/src/tree.c +++ b/src/tree.c @@ -93,21 +93,34 @@ ofi_rbmap_create(int (*compare)(struct ofi_rbmap *map, void *key, void *data)) return map; } -static void ofi_delete_tree(struct ofi_rbmap *map, struct ofi_rbnode *node) +static int ofi_free_node(struct ofi_rbmap *map, struct ofi_rbnode *node, + void *context) { - if (node == &map->sentinel) - return; - - ofi_delete_tree(map, node->left); - ofi_delete_tree(map, node->right); free(node); + return FI_SUCCESS; +} + +int ofi_rbmap_foreach(struct ofi_rbmap *map, struct ofi_rbnode *root, + ofi_rbmap_node_func_t func, void *context) +{ + int ret; + if (root == &map->sentinel) + return FI_SUCCESS; + + ret = ofi_rbmap_foreach(map, root->left, func, context); + if (ret) + return ret; + ret = ofi_rbmap_foreach(map, root->right, func, context); + if (ret) + return ret; + return func(map, root, context); } void ofi_rbmap_cleanup(struct ofi_rbmap *map) { struct ofi_rbnode *node; - ofi_delete_tree(map, map->root); + (void) ofi_rbmap_foreach(map, map->root, ofi_free_node, NULL); while (map->free_list) { node = map->free_list; map->free_list = node->right;