]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: add list_sort(), list_dup()
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 24 May 2018 07:04:48 +0000 (07:04 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 25 May 2018 16:16:15 +0000 (16:16 +0000)
* list_dup(): duplicates a linked list
* list_sort(): in-place sort of linked list w/ ascending quicksort

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/linklist.c
lib/linklist.h

index 2306dd6d0079a5d5ce10ff1f7dd0a6376152761e..3a35b250ca560b1ed533b25427c6c7a8314f3131 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <zebra.h>
+#include <stdlib.h>
 
 #include "linklist.h"
 #include "memory.h"
@@ -296,3 +297,41 @@ void list_add_list(struct list *l, struct list *m)
        for (n = listhead(m); n; n = listnextnode(n))
                listnode_add(l, n->data);
 }
+
+struct list *list_dup(struct list *l)
+{
+       struct list *new = list_new();
+       struct listnode *ln;
+       void *data;
+
+       new->cmp = l->cmp;
+       new->del = l->del;
+
+       for (ALL_LIST_ELEMENTS_RO(l, ln, data))
+               listnode_add(new, data);
+
+       return new;
+}
+
+void list_sort(struct list *list, int (*cmp)(const void **, const void **))
+{
+       struct listnode *ln, *nn;
+       int i = -1;
+       void *data;
+       size_t n = list->count;
+       void **items = XCALLOC(MTYPE_TMP, (sizeof(void *)) * n);
+       int (*realcmp)(const void *, const void *) =
+               (int (*)(const void *, const void *))cmp;
+
+       for (ALL_LIST_ELEMENTS(list, ln, nn, data)) {
+               items[++i] = data;
+               list_delete_node(list, ln);
+       }
+
+       qsort(items, n, sizeof(void *), realcmp);
+
+       for (unsigned int i = 0; i < n; ++i)
+               listnode_add(list, items[i]);
+
+       XFREE(MTYPE_TMP, items);
+}
index ae150158a625eee1f47d7f9c93374a198d63d731..d6d9b5e087a1563aa6f70333b2bb725c84636bec 100644 (file)
@@ -73,6 +73,9 @@ extern void listnode_move_to_tail(struct list *, struct listnode *);
 extern void listnode_delete(struct list *, void *);
 extern struct listnode *listnode_lookup(struct list *, void *);
 extern void *listnode_head(struct list *);
+extern struct list *list_dup(struct list *l);
+extern void list_sort(struct list *list,
+                     int (*cmp)(const void *, const void *));
 
 /*
  * The usage of list_delete is being transitioned to pass in