replaced AVL by Daniel A. Nagy (GPLv2) with an adaptation of libavl by Ben Pfaff (LGPL) that uses exactly the memory footprint of the first
Costa Tsaousis committed
Jul 29, 2016 at 01:44 UTC
f39f8dc7a65d06e88afcc70927862803b2b59f10
5 files changed
+297
-379
profile/benchmark-dictionary.c
+4
-1
@@ -8,6 +8,7 @@
8
*/
9
10
#include <stdio.h>
11
+#include <stdlib.h>
12
#include <inttypes.h>
13
14
#include "dictionary.h"
@@ -19,6 +20,8 @@ struct myvalue {
20
int i;
21
};
22
23
+void netdata_cleanup_and_exit(int ret) { exit(ret); }
24
+
25
int main(int argc, char **argv) {
26
if(argc || argv) {;}
27
@@ -30,7 +33,7 @@ int main(int argc, char **argv) {
33
unsigned long long dt;
34
char buf[100 + 1];
35
struct myvalue value, *v;
33
- int i, max = 100000, max2;
36
+ int i, max = 30000000, max2;
37
38
// ------------------------------------------------------------------------
39
src/avl.c
+275
-336
@@ -1,343 +1,290 @@
1
-/*
2
- * ANSI C Library for maintainance of AVL Balanced Trees
3
- *
4
- * ref.:
5
- * G. M. Adelson-Velskij & E. M. Landis
6
- * Doklady Akad. Nauk SSSR 146 (1962), 263-266
7
- *
8
- * see also:
9
- * D. E. Knuth: The Art of Computer Programming Vol.3 (Sorting and Searching)
10
- *
11
- * (C) 2000 Daniel Nagy, Budapest University of Technology and Economics
12
- * Released under GNU General Public License (GPL) version 2
13
- *
14
- */
15
-
1
#ifdef HAVE_CONFIG_H
2
#include <config.h>
3
#endif
4
+// #include <assert.h>
5
+
6
#include "avl.h"
7
#include "log.h"
8
22
-/* Swing to the left
23
- * Warning: no balance maintainance
24
- */
25
-void avl_swl(avl** root) {
26
- avl* a = *root;
27
- avl* b = a->right;
28
- *root = b;
29
- a->right = b->left;
30
- b->left = a;
31
-}
9
+/* ------------------------------------------------------------------------- */
10
+/*
11
+ * avl_insert(), avl_remove() and avl_search()
12
+ * are adaptations (by Costa Tsaousis) of the AVL algorithm found in libavl
13
+ * v2.0.3, so that they do not use any memory allocations and their memory
14
+ * footprint is optimized (by eliminating non-necessary data members).
15
+ *
16
+ * libavl - library for manipulation of binary trees.
17
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
18
+ * Foundation, Inc.
19
+ * GNU Lesser General Public License
20
+*/
21
33
-/* Swing to the right
34
- * Warning: no balance maintainance
35
- */
36
-void avl_swr(avl** root) {
37
- avl* a = *root;
38
- avl* b = a->left;
39
- *root = b;
40
- a->left = b->right;
41
- b->right = a;
42
-}
22
44
-/* Balance maintainance after especially nasty swings
45
- */
46
-void avl_nasty(avl* root) {
47
- switch (root->balance) {
48
- case -1:
49
- root->left->balance = 0;
50
- root->right->balance = 1;
51
- break;
52
- case 1:
53
- root->left->balance = -1;
54
- root->right->balance = 0;
55
- break;
56
- case 0:
57
- root->left->balance = 0;
58
- root->right->balance = 0;
59
- }
60
- root->balance = 0;
61
-}
23
+/* Search |tree| for an item matching |item|, and return it if found.
24
+ Otherwise return |NULL|. */
25
+avl *avl_search(avl_tree *tree, avl *item) {
26
+ avl *p;
27
63
-/* Public methods */
28
+ // assert (tree != NULL && item != NULL);
29
65
-/* Insert element a into the AVL tree t
66
- * returns 1 if the depth of the tree has grown
67
- * Warning: do not insert elements already present
68
- */
69
-int avl_insert(avl_tree* t, avl* a) {
70
- /* initialize */
71
- a->left = 0;
72
- a->right = 0;
73
- a->balance = 0;
74
- /* insert into an empty tree */
75
- if (!t->root) {
76
- t->root = a;
77
- return 1;
78
- }
79
-
80
- if (t->compar(t->root, a) > 0) {
81
- /* insert into the left subtree */
82
- if (t->root->left) {
83
- avl_tree left_subtree;
84
- left_subtree.root = t->root->left;
85
- left_subtree.compar = t->compar;
86
- if (avl_insert(&left_subtree, a)) {
87
- switch (t->root->balance--) {
88
- case 1:
89
- return 0;
90
- case 0:
91
- return 1;
92
- }
93
- if (t->root->left->balance < 0) {
94
- avl_swr(&(t->root));
95
- t->root->balance = 0;
96
- t->root->right->balance = 0;
97
- } else {
98
- avl_swl(&(t->root->left));
99
- avl_swr(&(t->root));
100
- avl_nasty(t->root);
101
- }
102
- } else
103
- t->root->left = left_subtree.root;
104
- return 0;
105
- } else {
106
- t->root->left = a;
107
- if (t->root->balance--)
108
- return 0;
109
- return 1;
110
- }
111
- } else {
112
- /* insert into the right subtree */
113
- if (t->root->right) {
114
- avl_tree right_subtree;
115
- right_subtree.root = t->root->right;
116
- right_subtree.compar = t->compar;
117
- if (avl_insert(&right_subtree, a)) {
118
- switch (t->root->balance++) {
119
- case -1:
120
- return 0;
121
- case 0:
122
- return 1;
123
- }
124
- if (t->root->right->balance > 0) {
125
- avl_swl(&(t->root));
126
- t->root->balance = 0;
127
- t->root->left->balance = 0;
128
- } else {
129
- avl_swr(&(t->root->right));
130
- avl_swl(&(t->root));
131
- avl_nasty(t->root);
132
- }
133
- } else
134
- t->root->right = right_subtree.root;
135
- return 0;
136
- } else {
137
- t->root->right = a;
138
- if (t->root->balance++)
139
- return 0;
140
- return 1;
141
- }
142
- }
143
-}
30
+ for (p = tree->root; p != NULL; ) {
31
+ int cmp = tree->compar(item, p);
32
145
-/* Remove an element a from the AVL tree t
146
- * returns -1 if the depth of the tree has shrunk
147
- * Warning: if the element is not present in the tree,
148
- * returns 0 as if it had been removed succesfully.
149
- */
150
-int avl_remove(avl_tree* t, avl* a) {
151
- int b;
152
- if (t->root == a)
153
- return avl_removeroot(t);
154
- b = t->compar(t->root, a);
155
- if (b >= 0) {
156
- /* remove from the left subtree */
157
- int ch;
158
- avl_tree left_subtree;
159
- if ((left_subtree.root = t->root->left)) {
160
- left_subtree.compar = t->compar;
161
- ch = avl_remove(&left_subtree, a);
162
- t->root->left = left_subtree.root;
163
- if (ch) {
164
- switch (t->root->balance++) {
165
- case -1:
166
- return -1;
167
- case 0:
168
- return 0;
169
- }
170
- switch (t->root->right->balance) {
171
- case 0:
172
- avl_swl(&(t->root));
173
- t->root->balance = -1;
174
- t->root->left->balance = 1;
175
- return 0;
176
- case 1:
177
- avl_swl(&(t->root));
178
- t->root->balance = 0;
179
- t->root->left->balance = 0;
180
- return -1;
181
- }
182
- avl_swr(&(t->root->right));
183
- avl_swl(&(t->root));
184
- avl_nasty(t->root);
185
- return -1;
186
- }
187
- }
188
- }
189
- if (b <= 0) {
190
- /* remove from the right subtree */
191
- int ch;
192
- avl_tree right_subtree;
193
- if ((right_subtree.root = t->root->right)) {
194
- right_subtree.compar = t->compar;
195
- ch = avl_remove(&right_subtree, a);
196
- t->root->right = right_subtree.root;
197
- if (ch) {
198
- switch (t->root->balance--) {
199
- case 1:
200
- return -1;
201
- case 0:
202
- return 0;
203
- }
204
- switch (t->root->left->balance) {
205
- case 0:
206
- avl_swr(&(t->root));
207
- t->root->balance = 1;
208
- t->root->right->balance = -1;
209
- return 0;
210
- case -1:
211
- avl_swr(&(t->root));
212
- t->root->balance = 0;
213
- t->root->right->balance = 0;
214
- return -1;
215
- }
216
- avl_swl(&(t->root->left));
217
- avl_swr(&(t->root));
218
- avl_nasty(t->root);
219
- return -1;
220
- }
221
- }
222
- }
223
- return 0;
224
-}
33
+ if (cmp < 0)
34
+ p = p->avl_link[0];
35
+ else if (cmp > 0)
36
+ p = p->avl_link[1];
37
+ else /* |cmp == 0| */
38
+ return p;
39
+ }
40
226
-/* Remove the root of the AVL tree t
227
- * Warning: dumps core if t is empty
228
- */
229
-int avl_removeroot(avl_tree* t) {
230
- int ch;
231
- avl* a;
232
- if (!t->root->left) {
233
- if (!t->root->right) {
234
- t->root = 0;
235
- return -1;
236
- }
237
- t->root = t->root->right;
238
- return -1;
239
- }
240
- if (!t->root->right) {
241
- t->root = t->root->left;
242
- return -1;
243
- }
244
- if (t->root->balance < 0) {
245
- /* remove from the left subtree */
246
- a = t->root->left;
247
- while (a->right)
248
- a = a->right;
249
- } else {
250
- /* remove from the right subtree */
251
- a = t->root->right;
252
- while (a->left)
253
- a = a->left;
254
- }
255
- ch = avl_remove(t, a);
256
- a->left = t->root->left;
257
- a->right = t->root->right;
258
- a->balance = t->root->balance;
259
- t->root = a;
260
- if (a->balance == 0)
261
- return ch;
262
- return 0;
41
+ return NULL;
42
}
43
265
-/* Iterate through elements in t from a range between a and b (inclusive)
266
- * for each element calls iter(a) until it returns 0
267
- * returns the last value returned by iterator or 0 if there were no calls
268
- * Warning: a<=b must hold
44
+/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
45
+ If a duplicate item is found in the tree,
46
+ returns a pointer to the duplicate without inserting |item|.
47
*/
270
-int avl_range(avl_tree* t, avl* a, avl* b, int (*iter)(avl*), avl** ret) {
271
- int x, c = 0;
272
- if (!t->root)
273
- return 0;
274
- x = t->compar(t->root, a);
275
- if (a != b) {
276
- if (x < 0) {
277
- x = t->compar(t->root, b);
278
- if (x > 0)
279
- x = 0;
280
- }
281
- }
282
- if (x >= 0) {
283
- /* search in the left subtree */
284
- avl_tree left_subtree;
285
- if ((left_subtree.root = t->root->left)) {
286
- left_subtree.compar = t->compar;
287
- if (!(c = avl_range(&left_subtree, a, b, iter, ret)))
288
- if (x > 0)
289
- return 0;
290
- }
291
- }
292
- if (x == 0) {
293
- if (!(c = iter(t->root))) {
294
- if (ret)
295
- *ret = t->root;
296
- return 0;
297
- }
298
- }
299
- if (x <= 0) {
300
- /* search in the right subtree */
301
- avl_tree right_subtree;
302
- if ((right_subtree.root = t->root->right)) {
303
- right_subtree.compar = t->compar;
304
- if (!(c = avl_range(&right_subtree, a, b, iter, ret)))
305
- if (x < 0)
306
- return 0;
307
- }
308
- }
309
- return c;
310
-}
311
-
312
-/* high performance searching - by ktsaou */
313
-avl *avl_search(avl_tree *t, avl *a) {
314
- avl *root = t->root;
315
-
316
- while(root) {
317
- int x = t->compar(root, a);
318
-
319
- if(x > 0) {
320
- root = root->left;
321
- continue;
322
- }
323
-
324
- if(x < 0) {
325
- root = root->right;
326
- continue;
327
- }
328
-
329
- return root;
330
- }
331
-
332
- return NULL;
48
+avl *avl_insert(avl_tree *tree, avl *item) {
49
+ avl *y, *z; /* Top node to update balance factor, and parent. */
50
+ avl *p, *q; /* Iterator, and parent. */
51
+ avl *n; /* Newly inserted node. */
52
+ avl *w; /* New root of rebalanced subtree. */
53
+ int dir; /* Direction to descend. */
54
+
55
+ unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */
56
+ int k = 0; /* Number of cached results. */
57
+
58
+ // assert(tree != NULL && item != NULL);
59
+
60
+ z = (avl *) &tree->root;
61
+ y = tree->root;
62
+ dir = 0;
63
+ for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir]) {
64
+ int cmp = tree->compar(item, p);
65
+ if (cmp == 0)
66
+ return p;
67
+
68
+ if (p->avl_balance != 0)
69
+ z = q, y = p, k = 0;
70
+ da[k++] = dir = (cmp > 0);
71
+ }
72
+
73
+ n = q->avl_link[dir] = item;
74
+
75
+ // tree->avl_count++;
76
+ n->avl_link[0] = n->avl_link[1] = NULL;
77
+ n->avl_balance = 0;
78
+ if (y == NULL) return n;
79
+
80
+ for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++)
81
+ if (da[k] == 0)
82
+ p->avl_balance--;
83
+ else
84
+ p->avl_balance++;
85
+
86
+ if (y->avl_balance == -2) {
87
+ avl *x = y->avl_link[0];
88
+ if (x->avl_balance == -1) {
89
+ w = x;
90
+ y->avl_link[0] = x->avl_link[1];
91
+ x->avl_link[1] = y;
92
+ x->avl_balance = y->avl_balance = 0;
93
+ }
94
+ else {
95
+ // assert (x->avl_balance == +1);
96
+ w = x->avl_link[1];
97
+ x->avl_link[1] = w->avl_link[0];
98
+ w->avl_link[0] = x;
99
+ y->avl_link[0] = w->avl_link[1];
100
+ w->avl_link[1] = y;
101
+ if (w->avl_balance == -1)
102
+ x->avl_balance = 0, y->avl_balance = +1;
103
+ else if (w->avl_balance == 0)
104
+ x->avl_balance = y->avl_balance = 0;
105
+ else /* |w->avl_balance == +1| */
106
+ x->avl_balance = -1, y->avl_balance = 0;
107
+ w->avl_balance = 0;
108
+ }
109
+ }
110
+ else if (y->avl_balance == +2) {
111
+ avl *x = y->avl_link[1];
112
+ if (x->avl_balance == +1) {
113
+ w = x;
114
+ y->avl_link[1] = x->avl_link[0];
115
+ x->avl_link[0] = y;
116
+ x->avl_balance = y->avl_balance = 0;
117
+ }
118
+ else {
119
+ // assert (x->avl_balance == -1);
120
+ w = x->avl_link[0];
121
+ x->avl_link[0] = w->avl_link[1];
122
+ w->avl_link[1] = x;
123
+ y->avl_link[1] = w->avl_link[0];
124
+ w->avl_link[0] = y;
125
+ if (w->avl_balance == +1)
126
+ x->avl_balance = 0, y->avl_balance = -1;
127
+ else if (w->avl_balance == 0)
128
+ x->avl_balance = y->avl_balance = 0;
129
+ else /* |w->avl_balance == -1| */
130
+ x->avl_balance = +1, y->avl_balance = 0;
131
+ w->avl_balance = 0;
132
+ }
133
+ }
134
+ else return n;
135
+
136
+ z->avl_link[y != z->avl_link[0]] = w;
137
+
138
+ // tree->avl_generation++;
139
+ return n;
140
}
141
335
-void avl_init(avl_tree *t, int (*compar)(void *a, void *b)) {
336
- t->root = NULL;
337
- t->compar = compar;
142
+/* Deletes from |tree| and returns an item matching |item|.
143
+ Returns a null pointer if no matching item found. */
144
+avl *avl_remove(avl_tree *tree, avl *item) {
145
+ /* Stack of nodes. */
146
+ avl *pa[AVL_MAX_HEIGHT]; /* Nodes. */
147
+ unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */
148
+ int k; /* Stack pointer. */
149
+
150
+ avl *p; /* Traverses tree to find node to delete. */
151
+ int cmp; /* Result of comparison between |item| and |p|. */
152
+
153
+ // assert (tree != NULL && item != NULL);
154
+
155
+ k = 0;
156
+ p = (avl *) &tree->root;
157
+ for(cmp = -1; cmp != 0; cmp = tree->compar(item, p)) {
158
+ int dir = (cmp > 0);
159
+
160
+ pa[k] = p;
161
+ da[k++] = dir;
162
+
163
+ p = p->avl_link[dir];
164
+ if(p == NULL) return NULL;
165
+ }
166
+
167
+ item = p;
168
+
169
+ if (p->avl_link[1] == NULL)
170
+ pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];
171
+ else {
172
+ avl *r = p->avl_link[1];
173
+ if (r->avl_link[0] == NULL) {
174
+ r->avl_link[0] = p->avl_link[0];
175
+ r->avl_balance = p->avl_balance;
176
+ pa[k - 1]->avl_link[da[k - 1]] = r;
177
+ da[k] = 1;
178
+ pa[k++] = r;
179
+ }
180
+ else {
181
+ avl *s;
182
+ int j = k++;
183
+
184
+ for (;;) {
185
+ da[k] = 0;
186
+ pa[k++] = r;
187
+ s = r->avl_link[0];
188
+ if (s->avl_link[0] == NULL) break;
189
+
190
+ r = s;
191
+ }
192
+
193
+ s->avl_link[0] = p->avl_link[0];
194
+ r->avl_link[0] = s->avl_link[1];
195
+ s->avl_link[1] = p->avl_link[1];
196
+ s->avl_balance = p->avl_balance;
197
+
198
+ pa[j - 1]->avl_link[da[j - 1]] = s;
199
+ da[j] = 1;
200
+ pa[j] = s;
201
+ }
202
+ }
203
+
204
+ // assert (k > 0);
205
+ while (--k > 0) {
206
+ avl *y = pa[k];
207
+
208
+ if (da[k] == 0) {
209
+ y->avl_balance++;
210
+ if (y->avl_balance == +1) break;
211
+ else if (y->avl_balance == +2) {
212
+ avl *x = y->avl_link[1];
213
+ if (x->avl_balance == -1) {
214
+ avl *w;
215
+ // assert (x->avl_balance == -1);
216
+ w = x->avl_link[0];
217
+ x->avl_link[0] = w->avl_link[1];
218
+ w->avl_link[1] = x;
219
+ y->avl_link[1] = w->avl_link[0];
220
+ w->avl_link[0] = y;
221
+ if (w->avl_balance == +1)
222
+ x->avl_balance = 0, y->avl_balance = -1;
223
+ else if (w->avl_balance == 0)
224
+ x->avl_balance = y->avl_balance = 0;
225
+ else /* |w->avl_balance == -1| */
226
+ x->avl_balance = +1, y->avl_balance = 0;
227
+ w->avl_balance = 0;
228
+ pa[k - 1]->avl_link[da[k - 1]] = w;
229
+ }
230
+ else {
231
+ y->avl_link[1] = x->avl_link[0];
232
+ x->avl_link[0] = y;
233
+ pa[k - 1]->avl_link[da[k - 1]] = x;
234
+ if (x->avl_balance == 0) {
235
+ x->avl_balance = -1;
236
+ y->avl_balance = +1;
237
+ break;
238
+ }
239
+ else x->avl_balance = y->avl_balance = 0;
240
+ }
241
+ }
242
+ }
243
+ else
244
+ {
245
+ y->avl_balance--;
246
+ if (y->avl_balance == -1) break;
247
+ else if (y->avl_balance == -2) {
248
+ avl *x = y->avl_link[0];
249
+ if (x->avl_balance == +1) {
250
+ avl *w;
251
+ // assert (x->avl_balance == +1);
252
+ w = x->avl_link[1];
253
+ x->avl_link[1] = w->avl_link[0];
254
+ w->avl_link[0] = x;
255
+ y->avl_link[0] = w->avl_link[1];
256
+ w->avl_link[1] = y;
257
+ if (w->avl_balance == -1)
258
+ x->avl_balance = 0, y->avl_balance = +1;
259
+ else if (w->avl_balance == 0)
260
+ x->avl_balance = y->avl_balance = 0;
261
+ else /* |w->avl_balance == +1| */
262
+ x->avl_balance = -1, y->avl_balance = 0;
263
+ w->avl_balance = 0;
264
+ pa[k - 1]->avl_link[da[k - 1]] = w;
265
+ }
266
+ else {
267
+ y->avl_link[0] = x->avl_link[1];
268
+ x->avl_link[1] = y;
269
+ pa[k - 1]->avl_link[da[k - 1]] = x;
270
+ if (x->avl_balance == 0) {
271
+ x->avl_balance = +1;
272
+ y->avl_balance = -1;
273
+ break;
274
+ }
275
+ else x->avl_balance = y->avl_balance = 0;
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ // tree->avl_count--;
282
+ // tree->avl_generation++;
283
+ return item;
284
}
285
286
/* ------------------------------------------------------------------------- */
287
+// these functions are (C) Costa Tsaousis
288
289
void avl_read_lock(avl_tree_lock *t) {
290
#ifndef AVL_WITHOUT_PTHREADS
@@ -396,30 +343,22 @@ avl *avl_search_lock(avl_tree_lock *t, avl *a) {
343
return ret;
344
}
345
399
-int avl_range_lock(avl_tree_lock *t, avl *a, avl *b, int (*iter)(avl *), avl **ret) {
400
- avl_read_lock(t);
401
- int ret2 = avl_range(&t->avl_tree, a, b, iter, ret);
402
- avl_unlock(t);
403
- return ret2;
404
-}
405
-
406
-int avl_removeroot_lock(avl_tree_lock *t) {
346
+avl * avl_remove_lock(avl_tree_lock *t, avl *a) {
347
avl_write_lock(t);
408
- int ret = avl_removeroot(&t->avl_tree);
348
+ avl *ret = avl_remove(&t->avl_tree, a);
349
avl_unlock(t);
350
return ret;
351
}
352
413
-int avl_remove_lock(avl_tree_lock *t, avl *a) {
353
+avl *avl_insert_lock(avl_tree_lock *t, avl *a) {
354
avl_write_lock(t);
415
- int ret = avl_remove(&t->avl_tree, a);
355
+ avl * ret = avl_insert(&t->avl_tree, a);
356
avl_unlock(t);
357
return ret;
358
}
359
420
-int avl_insert_lock(avl_tree_lock *t, avl *a) {
421
- avl_write_lock(t);
422
- int ret = avl_insert(&t->avl_tree, a);
423
- avl_unlock(t);
424
- return ret;
360
+void avl_init(avl_tree *t, int (*compar)(void *a, void *b)) {
361
+ t->root = NULL;
362
+ t->compar = compar;
363
}
364
+
src/avl.h
+12
-36
@@ -1,20 +1,12 @@
1
-/*
2
- * ANSI C Library for maintainance of AVL Balanced Trees
3
- *
4
- * ref.:
5
- * G. M. Adelson-Velskij & E. M. Landis
6
- * Doklady Akad. Nauk SSSR 146 (1962), 263-266
7
- *
8
- * see also:
9
- * D. E. Knuth: The Art of Computer Programming Vol.3 (Sorting and Searching)
10
- *
11
- * (C) 2000 Daniel Nagy, Budapest University of Technology and Economics
12
- * Released under GNU General Public License (GPL) version 2
13
- *
14
- */
1
+
2
#ifndef _AVL_H
3
#define _AVL_H 1
4
5
+/* Maximum AVL tree height. */
6
+#ifndef AVL_MAX_HEIGHT
7
+#define AVL_MAX_HEIGHT 92
8
+#endif
9
+
10
#ifndef AVL_WITHOUT_PTHREADS
11
#include <pthread.h>
12
@@ -34,15 +26,13 @@
26
27
/* One element of the AVL tree */
28
typedef struct avl {
37
- struct avl* left;
38
- struct avl* right;
39
- signed char balance;
29
+ struct avl *avl_link[2]; /* Subtrees. */
30
+ signed char avl_balance; /* Balance factor. */
31
} avl;
32
33
/* An AVL tree */
34
typedef struct avl_tree {
35
avl *root;
45
-
36
int (*compar)(void *a, void *b);
37
} avl_tree;
38
@@ -64,30 +54,16 @@ typedef struct avl_tree_lock {
54
* returns 1 if the depth of the tree has grown
55
* Warning: do not insert elements already present
56
*/
67
-int avl_insert_lock(avl_tree_lock *t, avl *a);
68
-int avl_insert(avl_tree *t, avl *a);
57
+avl *avl_insert_lock(avl_tree_lock *t, avl *a);
58
+avl *avl_insert(avl_tree *t, avl *a);
59
60
/* Remove an element a from the AVL tree t
61
* returns -1 if the depth of the tree has shrunk
62
* Warning: if the element is not present in the tree,
63
* returns 0 as if it had been removed succesfully.
64
*/
75
-int avl_remove_lock(avl_tree_lock *t, avl *a);
76
-int avl_remove(avl_tree *t, avl *a);
77
-
78
-/* Remove the root of the AVL tree t
79
- * Warning: dumps core if t is empty
80
- */
81
-int avl_removeroot_lock(avl_tree_lock *t);
82
-int avl_removeroot(avl_tree *t);
83
-
84
-/* Iterate through elements in t from a range between a and b (inclusive)
85
- * for each element calls iter(a) until it returns 0
86
- * returns the last value returned by iterator or 0 if there were no calls
87
- * Warning: a<=b must hold
88
- */
89
-int avl_range_lock(avl_tree_lock *t, avl *a, avl *b, int (*iter)(avl *), avl **ret);
90
-int avl_range(avl_tree *t, avl *a, avl *b, int (*iter)(avl *), avl **ret);
65
+avl *avl_remove_lock(avl_tree_lock *t, avl *a);
66
+avl *avl_remove(avl_tree *t, avl *a);
67
68
/* Iterate through elements in t equal to a
69
* for each element calls iter(a) until it returns 0
src/dictionary.c
+4
-4
@@ -280,8 +280,8 @@ int dictionary_del(DICTIONARY *dict, const char *name) {
280
static int dictionary_walker(avl *a, int (*callback)(void *entry, void *data), void *data) {
281
int total = 0, ret = 0;
282
283
- if(a->right) {
284
- ret = dictionary_walker(a->right, callback, data);
283
+ if(a->avl_link[0]) {
284
+ ret = dictionary_walker(a->avl_link[0], callback, data);
285
if(ret < 0) return ret;
286
total += ret;
287
}
@@ -290,8 +290,8 @@ static int dictionary_walker(avl *a, int (*callback)(void *entry, void *data), v
290
if(ret < 0) return ret;
291
total += ret;
292
293
- if(a->left) {
294
- ret = dictionary_walker(a->left, callback, data);
293
+ if(a->avl_link[1]) {
294
+ ret = dictionary_walker(a->avl_link[1], callback, data);
295
if (ret < 0) return ret;
296
total += ret;
297
}
src/rrd.c
+2
-2
@@ -86,9 +86,9 @@ avl_tree_lock rrdset_root_index_name = {
86
AVL_LOCK_INITIALIZER
87
};
88
89
-int rrdset_index_add_name(RRDSET *st) {
89
+RRDSET *rrdset_index_add_name(RRDSET *st) {
90
// fprintf(stderr, "ADDING: %s (name: %s)\n", st->id, st->name);
91
- return avl_insert_lock(&rrdset_root_index_name, (avl *) (&st->avlname));
91
+ return (RRDSET *)avl_insert_lock(&rrdset_root_index_name, (avl *) (&st->avlname));
92
}
93
94
#define rrdset_index_del_name(st) avl_remove_lock(&rrdset_root_index_name, (avl *)(&st->avlname))