From 0d9a72de217354ec6921b4218bc0600605bfef1b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Wed, 20 Jan 2016 21:02:03 -0500 Subject: [PATCH] ircd: radixtree: add irc_radixtree_foreach_start_from() which uses irc_radixtree_elem_find() to find the starting point --- include/irc_radixtree.h | 12 ++++++++++++ ircd/irc_radixtree.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/irc_radixtree.h b/include/irc_radixtree.h index a2b59078..3d504e01 100644 --- a/include/irc_radixtree.h +++ b/include/irc_radixtree.h @@ -55,6 +55,9 @@ struct irc_radixtree_iteration_state #define IRC_RADIXTREE_FOREACH(element, state, dict) \ for (irc_radixtree_foreach_start((dict), (state)); (element = irc_radixtree_foreach_cur((dict), (state))); irc_radixtree_foreach_next((dict), (state))) +#define IRC_RADIXTREE_FOREACH_FROM(element, state, dict, key) \ + for (irc_radixtree_foreach_start_from((dict), (state), (key)); (element = irc_radixtree_foreach_cur((dict), (state))); irc_radixtree_foreach_next((dict), (state))) + /* * irc_radixtree_create() creates a new patricia tree of the defined resolution. * compare_cb is the canonizing function. @@ -100,6 +103,15 @@ extern void *irc_radixtree_search(struct irc_radixtree *dtree, void *(*foreach_c */ extern void irc_radixtree_foreach_start(struct irc_radixtree *dtree, struct irc_radixtree_iteration_state *state); +/* + * irc_radixtree_foreach_start_from() begins an iteration over all items, + * starting with the item specified by `key`. If there is only one iteration + * in progress at a time, it is permitted to remove the current element + * of the iteration (but not any other element). + * Use NULL as a key to have it start at the beginning. + */ +extern void irc_radixtree_foreach_start_from(struct irc_radixtree *dtree, struct irc_radixtree_iteration_state *state, const char *key); + /* * irc_radixtree_foreach_cur() returns the current element of the iteration, * or NULL if there are no more elements. diff --git a/ircd/irc_radixtree.c b/ircd/irc_radixtree.c index 9ede33f8..008e2335 100644 --- a/ircd/irc_radixtree.c +++ b/ircd/irc_radixtree.c @@ -609,6 +609,41 @@ irc_radixtree_elem_find(struct irc_radixtree *dict, const char *key) return &delem->leaf; } +/* + * irc_radixtree_foreach_start_from(struct irc_radixtree *dtree, struct irc_radixtree_iteration_state *state, const char *key) + * + * Starts iteration from a specified key, by wrapping irc_radixtree_elem_find(). + * + * Inputs: + * - patricia tree object + * - iterator + * - key to start from + * + * Outputs: + * - none + * + * Side Effects: + * - the iterator's state is initialized at a specific point + */ +void +irc_radixtree_foreach_start_from(struct irc_radixtree *dtree, struct irc_radixtree_iteration_state *state, const char *key) +{ + s_assert(dtree != NULL); + s_assert(state != NULL); + + if (key != NULL) + { + STATE_CUR(state) = NULL; + STATE_NEXT(state) = irc_radixtree_elem_find(dtree, key); + + /* make STATE_CUR point to selected item and STATE_NEXT point to + * next item in the tree */ + irc_radixtree_foreach_next(dtree, state); + } + else + irc_radixtree_foreach_start(dtree, state); +} + /* * irc_radixtree_add(struct irc_radixtree *dtree, const char *key, void *data) *