Skip to content

Commit f7f7986

Browse files
committed
nvl: use a red-black tree to keep track of name-value pairs
Instead of using an unbalanced binary search tree, use a balanced one. This should both improve the performance and make it more predictable. Signed-off-by: Josef 'Jeff' Sipek <[email protected]>
1 parent 51cfd49 commit f7f7986

File tree

7 files changed

+26
-26
lines changed

7 files changed

+26
-26
lines changed

fmt_cbor.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -234,21 +234,21 @@ int cbor_pack_map_end(struct buffer *buffer, size_t npairs)
234234

235235
int cbor_pack_map_val(struct buffer *buffer, struct val *val)
236236
{
237-
struct bst_tree *tree = &val->_set_nvl.values;
237+
struct rb_tree *tree = &val->_set_nvl.values;
238238
struct nvpair *cur;
239239
size_t npairs;
240240
int ret;
241241

242242
if (val->type != VT_NVL)
243243
return -EINVAL;
244244

245-
npairs = bst_numnodes(tree);
245+
npairs = rb_numnodes(tree);
246246

247247
ret = cbor_pack_map_start(buffer, npairs);
248248
if (ret)
249249
return ret;
250250

251-
bst_for_each(tree, cur) {
251+
rb_for_each(tree, cur) {
252252
ret = cbor_pack_str(buffer, cur->name);
253253
if (ret)
254254
return ret;

include/jeffpc/nvl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct nvlist {
3434

3535
/* do not access these directly */
3636
struct nvpair {
37-
struct bst_node node;
37+
struct rb_node node;
3838

3939
struct str *name;
4040
struct val *value;

include/jeffpc/val.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include <jeffpc/error.h>
3232
#include <jeffpc/types.h>
3333
#include <jeffpc/list.h>
34-
#include <jeffpc/bst.h>
34+
#include <jeffpc/rbtree.h>
3535

3636
/*
3737
* A typed value structure.
@@ -101,7 +101,7 @@ struct val {
101101
* a balanced binary search tree implementation, we
102102
* should switch to it.
103103
*/
104-
struct bst_tree values;
104+
struct rb_tree values;
105105
} nvl;
106106

107107
/*
@@ -132,7 +132,7 @@ struct val {
132132
size_t nelem;
133133
} _set_array;
134134
struct {
135-
struct bst_tree values;
135+
struct rb_tree values;
136136
} _set_nvl;
137137
};
138138
};

nvl.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static struct nvpair *find(struct nvlist *nvl, const char *name)
4949
.name = &name_str,
5050
};
5151

52-
return bst_find(&nvl->val._set_nvl.values, &key, NULL);
52+
return rb_find(&nvl->val._set_nvl.values, &key, NULL);
5353
}
5454

5555
/*
@@ -58,13 +58,13 @@ static struct nvpair *find(struct nvlist *nvl, const char *name)
5858

5959
const struct nvpair *nvl_iter_start(struct nvlist *nvl)
6060
{
61-
return bst_first(&nvl->val._set_nvl.values);
61+
return rb_first(&nvl->val._set_nvl.values);
6262
}
6363

6464
const struct nvpair *nvl_iter_next(struct nvlist *nvl,
6565
const struct nvpair *prev)
6666
{
67-
return bst_next(&nvl->val._set_nvl.values, (void *) prev);
67+
return rb_next(&nvl->val._set_nvl.values, (void *) prev);
6868
}
6969

7070
/*
@@ -133,7 +133,7 @@ static inline int do_nvl_set(struct nvlist *nvl, const char *cname,
133133
return -ENOMEM;
134134
}
135135

136-
bst_add(&nvl->val._set_nvl.values, pair);
136+
rb_add(&nvl->val._set_nvl.values, pair);
137137
} else {
138138
str_putref(name);
139139
}
@@ -211,7 +211,7 @@ static int unset(struct nvlist *nvl, const char *name, enum val_type type,
211211
if (matchtype && (pair->value->type != type))
212212
return -ERANGE;
213213

214-
bst_remove(&nvl->val._set_nvl.values, pair);
214+
rb_remove(&nvl->val._set_nvl.values, pair);
215215

216216
__nvpair_free(pair);
217217

sexpr.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,13 @@ bool sexpr_equal(struct val *lhs, struct val *rhs)
381381
goto out;
382382
}
383383
case VT_NVL: {
384-
struct bst_tree *ltree = &lhs->_set_nvl.values;
385-
struct bst_tree *rtree = &rhs->_set_nvl.values;
384+
struct rb_tree *ltree = &lhs->_set_nvl.values;
385+
struct rb_tree *rtree = &rhs->_set_nvl.values;
386386
struct nvpair *lcur;
387387
struct nvpair *rcur;
388388

389-
lcur = bst_first(ltree);
390-
rcur = bst_first(rtree);
389+
lcur = rb_first(ltree);
390+
rcur = rb_first(rtree);
391391

392392
while (lcur && rcur) {
393393
ret = (str_cmp(lcur->name, rcur->name) == 0);
@@ -399,8 +399,8 @@ bool sexpr_equal(struct val *lhs, struct val *rhs)
399399
if (!ret)
400400
goto out;
401401

402-
lcur = bst_next(ltree, lcur);
403-
rcur = bst_next(rtree, rcur);
402+
lcur = rb_next(ltree, lcur);
403+
rcur = rb_next(rtree, rcur);
404404
}
405405

406406
/* if both sides reached the end, then they are equal */

val_dump.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,12 @@ static void do_val_dump_file(FILE *out, struct val *val, int indent)
126126
break;
127127
}
128128
case VT_NVL: {
129-
struct bst_tree *tree = &val->_set_nvl.values;
129+
struct rb_tree *tree = &val->_set_nvl.values;
130130
struct nvpair *cur;
131131

132-
fprintf(out, " items=%zu\n", bst_numnodes(tree));
132+
fprintf(out, " items=%zu\n", rb_numnodes(tree));
133133

134-
bst_for_each(tree, cur) {
134+
rb_for_each(tree, cur) {
135135
doindent(out, indent);
136136
fprintf(out, "name='%s' ", str_cstr(cur->name));
137137
do_val_dump_file(out, cur->value, indent + 1);

val_nvl.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -81,24 +81,24 @@ struct val *val_alloc_nvl(void)
8181
if (IS_ERR(val))
8282
return val;
8383

84-
bst_create(&val->_set_nvl.values, val_nvl_cmp, sizeof(struct nvpair),
84+
rb_create(&val->_set_nvl.values, val_nvl_cmp, sizeof(struct nvpair),
8585
offsetof(struct nvpair, node));
8686

8787
return val;
8888
}
8989

9090
void __val_free_nvl(struct val *val)
9191
{
92-
struct bst_cookie cookie;
92+
struct rb_cookie cookie;
9393
struct nvpair *cur;
9494

9595
ASSERT(val);
9696
ASSERT3U(refcnt_read(&val->refcnt), ==, 0);
9797
ASSERT3U(val->type, ==, VT_NVL);
9898

99-
memset(&cookie, 0, sizeof(struct bst_cookie));
100-
while ((cur = bst_destroy_nodes(&val->_set_nvl.values, &cookie)))
99+
memset(&cookie, 0, sizeof(struct rb_cookie));
100+
while ((cur = rb_destroy_nodes(&val->_set_nvl.values, &cookie)))
101101
__nvpair_free(cur);
102102

103-
bst_destroy(&val->_set_nvl.values);
103+
rb_destroy(&val->_set_nvl.values);
104104
}

0 commit comments

Comments
 (0)