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