From 3a9689652d9297b81c94964388bae9f8191b88a5 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Sun, 2 Jun 2024 14:11:37 +0200 Subject: [PATCH] radix_tree: add radix_tree_values To more easily adopt radix_tree over existing code base, add abstraction over 'radix_tree_iterate' which basically builds an array of all traversed values, and then it's just easy to go over all array elements. TODO: code should be converted to use radix_tree_iterate() directly as it's more efficient. Note: it can be possibly to rewrite recursive _iterate() usage to linear travesal, not sure whether it's worth the effort as conversion to 'radix_itree_iterator' is relatively simple. --- base/data-struct/radix-tree.c | 42 +++++++++++++++++++++++++++++++++++ base/data-struct/radix-tree.h | 6 +++++ 2 files changed, 48 insertions(+) diff --git a/base/data-struct/radix-tree.c b/base/data-struct/radix-tree.c index 52a1a0540..c766300b5 100644 --- a/base/data-struct/radix-tree.c +++ b/base/data-struct/radix-tree.c @@ -19,3 +19,45 @@ #endif //---------------------------------------------------------------- + +struct visitor { + struct radix_tree_iterator it; + unsigned pos, nr_entries; + union radix_value *values; +}; + +static bool _visitor(struct radix_tree_iterator *it, + const void *key, size_t keylen, + union radix_value v) +{ + struct visitor *vt = container_of(it, struct visitor, it); + + if (vt->pos >= vt->nr_entries) + return false; + + vt->values[vt->pos++] = v; + + return true; +} + +bool radix_tree_values(struct radix_tree *rt, const void *key, size_t keylen, + union radix_value **values, unsigned *nr_values) +{ + struct visitor vt = { + .it.visit = _visitor, + .nr_entries = rt->nr_entries, + .values = calloc(rt->nr_entries + 1, sizeof(union radix_value)), + }; + + if (vt.values) { + // build set of all values in current radix tree + radix_tree_iterate(rt, key, keylen, &vt.it); + *nr_values = vt.pos; + *values = vt.values; + return true; + } + + return false; +} + +//---------------------------------------------------------------- diff --git a/base/data-struct/radix-tree.h b/base/data-struct/radix-tree.h index 7f74769f7..b41105652 100644 --- a/base/data-struct/radix-tree.h +++ b/base/data-struct/radix-tree.h @@ -54,6 +54,12 @@ struct radix_tree_iterator { void radix_tree_iterate(struct radix_tree *rt, const void *key, size_t keylen, struct radix_tree_iterator *it); +// Alternative traversing radix_tree. +// Builds whole set all radix_tree nr_values values. +// After use, free(values). +bool radix_tree_values(struct radix_tree *rt, const void *key, size_t keylen, + union radix_value **values, unsigned *nr_values); + // Checks that some constraints on the shape of the tree are // being held. For debug only. bool radix_tree_is_well_formed(struct radix_tree *rt);