From: saravanank Date: Fri, 3 May 2019 13:57:57 +0000 (-0700) Subject: lib: implement utility function API which does the following X-Git-Tag: base_7.2~306^2~15 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=9b68e496042b7fc8bf2f27671fbfbc6f02541a17;p=matthieu%2Ffrr.git lib: implement utility function API which does the following 1. listnode_add_sort_nodup - This API adds to list only if no duplicate element available in the list. returns true/false 2. list_filter_out_nodes - This API deletes the nodes which satisfy the given condition. condition is passed as a func ptr in API. This function takes in node data(void ptr). Signed-off-by: Saravanan K --- diff --git a/lib/linklist.c b/lib/linklist.c index 40c4b27169..6cb639b27c 100644 --- a/lib/linklist.c +++ b/lib/linklist.c @@ -92,6 +92,46 @@ void listnode_add_head(struct list *list, void *val) list->count++; } +bool listnode_add_sort_nodup(struct list *list, void *val) +{ + struct listnode *n; + struct listnode *new; + int ret; + + assert(val != NULL); + + if (list->cmp) { + for (n = list->head; n; n = n->next) { + ret = (*list->cmp)(val, n->data); + if (ret < 0) { + new = listnode_new(); + new->data = val; + + new->next = n; + new->prev = n->prev; + + if (n->prev) + n->prev->next = new; + else + list->head = new; + n->prev = new; + list->count++; + return true; + } + /* found duplicate return false */ + if (ret == 0) + return false; + } + } + + new = listnode_new(); + new->data = val; + + LISTNODE_ATTACH(list, new); + + return true; +} + void listnode_add_sort(struct list *list, void *val) { struct listnode *n; @@ -242,6 +282,23 @@ void list_delete_all_node(struct list *list) list->count = 0; } +void list_filter_out_nodes(struct list *list, bool (*cond)(void *data)) +{ + struct listnode *node; + struct listnode *next; + void *data; + + assert(list); + + for (ALL_LIST_ELEMENTS(list, node, next, data)) { + if ((cond && cond(data)) || (!cond)) { + if (*list->del) + (*list->del)(data); + list_delete_node(list, node); + } + } +} + void list_delete(struct list **list) { assert(*list); diff --git a/lib/linklist.h b/lib/linklist.h index c30d8d314a..8761bc3d16 100644 --- a/lib/linklist.h +++ b/lib/linklist.h @@ -288,6 +288,39 @@ extern void list_delete_node(struct list *list, struct listnode *node); */ extern void list_add_list(struct list *list, struct list *add); +/* + * Delete all nodes which satisfy a condition from a list. + * Deletes the node if cond function returns true for the node. + * If function ptr passed is NULL, it deletes all nodes + * + * list + * list to operate on + * cond + * function pointer which takes node data as input and return TRUE or FALSE + */ + +extern void list_filter_out_nodes(struct list *list, bool (*cond)(void *data)); + +/* + * Insert a new element into a list with insertion sort if there is no + * duplicate element present in the list. This assumes the input list is + * sorted. If unsorted, it will check for duplicate until it finds out + * the position to do insertion sort with the unsorted list. + * + * If list->cmp is set, this function is used to determine the position to + * insert the new element. If it is not set, this function is equivalent to + * listnode_add. duplicate element is determined by cmp function returning 0. + * + * Runtime is O(N). + * + * list + * list to operate on + * + * val + * element to add + */ + +extern bool listnode_add_sort_nodup(struct list *list, void *val); /* List iteration macro. * Usage: for (ALL_LIST_ELEMENTS (...) { ... } * It is safe to delete the listnode using this macro.