From 5311e568cf40ead1b36c7d5c247531317ed5acde Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Mon, 26 Nov 2012 14:08:25 +0100 Subject: [PATCH] add xbt_fifo_search(), to search an item with a user-provided comparison function --- ChangeLog | 4 +++- include/xbt/fifo.h | 2 ++ src/xbt/fifo.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1c82035cb7..70c634d41b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,7 +22,9 @@ SimGrid (3.9) NOT RELEASED; urgency=low XBT: * Kill synchronized dynars, and xbt_dynar_dopar(). We cannot think of a usecase where it's really mandatory, and maintaining it was a pain in - our codebase. + our codebase. + * New: xbt_fifo_search(), search an item with a user-provided + comparison function instead of dumb pointer comparison. -- $date Da SimGrid team diff --git a/include/xbt/fifo.h b/include/xbt/fifo.h index ee3832c5ab..aaf2a372b0 100644 --- a/include/xbt/fifo.h +++ b/include/xbt/fifo.h @@ -7,6 +7,7 @@ #ifndef _XBT_FIFO_H #define _XBT_FIFO_H #include "xbt/misc.h" /* SG_BEGIN_DECL */ +#include "xbt/function_types.h" /* int_f_pvoid_pvoid_t */ SG_BEGIN_DECL() @@ -45,6 +46,7 @@ XBT_PUBLIC(xbt_fifo_item_t) xbt_fifo_unshift(xbt_fifo_t, void *); XBT_PUBLIC(void *) xbt_fifo_shift(xbt_fifo_t); XBT_PUBLIC(int) xbt_fifo_size(xbt_fifo_t); XBT_PUBLIC(int) xbt_fifo_is_in(xbt_fifo_t, void *); +XBT_PUBLIC(xbt_fifo_item_t) xbt_fifo_search_item(xbt_fifo_t f, int_f_pvoid_pvoid_t cmp_fun, void *closure); /** @} */ /** @defgroup XBT_fifo_direct Direct access to fifo elements diff --git a/src/xbt/fifo.c b/src/xbt/fifo.c index 7a425f687c..69ba34ad87 100644 --- a/src/xbt/fifo.c +++ b/src/xbt/fifo.c @@ -331,6 +331,40 @@ int xbt_fifo_is_in(xbt_fifo_t f, void *content) return 0; } +/** + * @brief Search the given element in the fifo using a comparison function + * + * This function allows to search an item with a user provided function instead + * of the pointer comparison used elsewhere in this module. Assume for example that you have a fifo of + * strings. You cannot use xbt_fifo_remove to remove, say, "TOTO" from it because internally, xbt_fifo_remove() + * will do something like "if (item->content == "toto"), then remove it". And the pointer to the item content + * and the pointer to "toto" will never match. As a solution, this function provides a way to search elements + * that are semanticaly equivalent instead of only syntaxically. So, removing "Toto" from a fifo can be + * achieved this way: + * + * int my_comparison_function(void *searched, void *seen) { + * return !strcmp(searched, seen); + * } + * + * xbt_fifo_remove_item(fifo, + * xbt_fifo_search_item(fifo, my_comparison_function, "Toto")); + * + * \param f a fifo list + * \param cmp_fun the comparison function. Prototype: void *a,void *b -> int. Semantic: returns true iff a=b + * @param closure the element to search. It will be provided as first argument to each call of cmp_fun + * \return the first item matching the comparison function, or NULL if no such item exists + */ +xbt_fifo_item_t xbt_fifo_search_item(xbt_fifo_t f, int_f_pvoid_pvoid_t cmp_fun, void *closure) { + xbt_fifo_item_t item = xbt_fifo_get_first_item(f); + while (item) { + if (cmp_fun(closure, item->content)) + return item; + item = item->next; + } + return NULL; + +} + /** * \param f a list * \return a table with the objects stored in \a f. -- 2.20.1