0b13f86c7c2fd514f50c6ade39c5dec1fdf14490
[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                         old_node->version = tree->version;
45                         goto update_only;
46                 }
47
48                 avl_delete(&tree->avl, anode);
49         }
50
51         avl_insert(&tree->avl, &node->avl);
52
53 update_only:
54         tree->update(tree, node, old_node);
55 }
56
57 void
58 vlist_flush(struct vlist_tree *tree)
59 {
60         struct vlist_node *node, *tmp;
61
62         avl_for_each_element_safe(&tree->avl, node, avl, tmp) {
63                 if (node->version == tree->version)
64                         continue;
65
66                 vlist_delete(tree, node);
67         }
68 }
69
70 void
71 vlist_flush_all(struct vlist_tree *tree)
72 {
73         tree->version++;
74         vlist_flush(tree);
75 }
76
77
78 void
79 __vlist_simple_init(struct vlist_simple_tree *tree, int offset)
80 {
81         INIT_LIST_HEAD(&tree->list);
82         tree->version = 1;
83         tree->head_offset = offset;
84 }
85
86 void
87 vlist_simple_delete(struct vlist_simple_tree *tree, struct vlist_simple_node *node)
88 {
89         char *ptr;
90
91         list_del(&node->list);
92         ptr = (char *) node - tree->head_offset;
93         free(ptr);
94 }
95
96 void
97 vlist_simple_flush(struct vlist_simple_tree *tree)
98 {
99         struct vlist_simple_node *n, *tmp;
100
101         list_for_each_entry_safe(n, tmp, &tree->list, list) {
102                 if (n->version == tree->version)
103                         continue;
104
105                 vlist_simple_delete(tree, n);
106         }
107 }
108
109 void
110 vlist_simple_flush_all(struct vlist_simple_tree *tree)
111 {
112         tree->version++;
113         vlist_simple_flush(tree);
114 }