proto-shell: add support for appending configuration data over multiple update_link...
[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 || node->version == -1) &&
61 tree->version != -1)
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 = -1;
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 || n->version == -1) &&
101 tree->version != -1)
102 continue;
103
104 vlist_simple_delete(tree, n);
105 }
106 }
107
108 void
109 vlist_simple_flush_all(struct vlist_simple_tree *tree)
110 {
111 tree->version = -1;
112 vlist_simple_flush(tree);
113 }