629cdb2bf228fdc4cf66b38e58d81d0c05b775aa
[project/netifd.git] / utils.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include "utils.h"
4
5 int
6 avl_strcmp(const void *k1, const void *k2, void *ptr)
7 {
8         return strcmp(k1, k2);
9 }
10
11 void
12 vlist_init(struct vlist_tree *tree, avl_tree_comp cmp, vlist_update_cb update)
13 {
14         tree->update = update;
15         tree->version = 1;
16
17         avl_init(&tree->avl, cmp, 0, tree);
18 }
19
20 void
21 vlist_delete(struct vlist_tree *tree, struct vlist_node *node)
22 {
23         if (!tree->no_delete)
24                 avl_delete(&tree->avl, &node->avl);
25         tree->update(tree, NULL, node);
26 }
27
28 void
29 vlist_add(struct vlist_tree *tree, struct vlist_node *node, void *key)
30 {
31         struct vlist_node *old_node = NULL;
32         struct avl_node *anode;
33
34         node->avl.key = key;
35         node->version = tree->version;
36
37         anode = avl_find(&tree->avl, key);
38         if (anode) {
39                 old_node = container_of(anode, struct vlist_node, avl);
40                 if (tree->keep_old || tree->no_delete) {
41                         old_node->version = tree->version;
42                         goto update_only;
43                 }
44
45                 avl_delete(&tree->avl, anode);
46         }
47
48         avl_insert(&tree->avl, &node->avl);
49
50 update_only:
51         tree->update(tree, node, old_node);
52 }
53
54 void
55 vlist_flush(struct vlist_tree *tree)
56 {
57         struct vlist_node *node, *tmp;
58
59         avl_for_each_element_safe(&tree->avl, node, avl, tmp) {
60                 if (node->version == tree->version)
61                         continue;
62
63                 vlist_delete(tree, node);
64         }
65 }
66
67 void
68 vlist_flush_all(struct vlist_tree *tree)
69 {
70         tree->version++;
71         vlist_flush(tree);
72 }
73
74
75 void
76 __vlist_simple_init(struct vlist_simple_tree *tree, int offset)
77 {
78         INIT_LIST_HEAD(&tree->list);
79         tree->version = 1;
80         tree->head_offset = offset;
81 }
82
83 void
84 vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node)
85 {
86         char *ptr;
87
88         list_del(&node->list);
89         ptr = (char *) node - tree->head_offset;
90         free(ptr);
91 }
92
93 void
94 vlist_simple_flush(struct vlist_simple_tree *tree)
95 {
96         struct vlist_simple_node *n, *tmp;
97
98         list_for_each_entry_safe(n, tmp, &tree->list, list) {
99                 if (n->version == tree->version)
100                         continue;
101
102                 vlist_simple_delete(tree, n);
103         }
104 }
105
106 void
107 vlist_simple_flush_all(struct vlist_simple_tree *tree)
108 {
109         tree->version++;
110         vlist_simple_flush(tree);
111 }