From: Vladimír Čunát Date: Thu, 28 Apr 2022 11:32:52 +0000 (+0200) Subject: lib/generic/trie: add trie_apply_with_key() X-Git-Tag: v5.5.1~16^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b26b286625aaaa64576f6496429c396ece97ec20;p=thirdparty%2Fknot-resolver.git lib/generic/trie: add trie_apply_with_key() --- diff --git a/lib/generic/trie.c b/lib/generic/trie.c index 2a666092c..51a37b93f 100644 --- a/lib/generic/trie.c +++ b/lib/generic/trie.c @@ -843,6 +843,26 @@ int trie_apply(trie_t *tbl, int (*f)(trie_val_t *, void *), void *d) return apply_trie(&tbl->root, f, d); } +/*! \brief Apply a function to every key + trie_val_t*, in order; a recursive solution. */ +static int apply_trie_with_key(node_t *t, int (*f)(const char *, uint32_t, trie_val_t *, void *), void *d) +{ + kr_require(t); + if (!isbranch(t)) + return f(t->leaf.key->chars, t->leaf.key->len, &t->leaf.val, d); + int child_count = bitmap_weight(t->branch.bitmap); + for (int i = 0; i < child_count; ++i) + ERR_RETURN(apply_trie_with_key(twig(t, i), f, d)); + return KNOT_EOK; +} + +int trie_apply_with_key(trie_t *tbl, int (*f)(const char *, uint32_t, trie_val_t *, void *), void *d) +{ + kr_require(tbl && f); + if (!tbl->weight) + return KNOT_EOK; + return apply_trie_with_key(&tbl->root, f, d); +} + /* These are all thin wrappers around static Tns* functions. */ trie_it_t* trie_it_begin(trie_t *tbl) { diff --git a/lib/generic/trie.h b/lib/generic/trie.h index e32b89b6a..8c4429767 100644 --- a/lib/generic/trie.h +++ b/lib/generic/trie.h @@ -83,6 +83,17 @@ int trie_get_leq(trie_t *tbl, const char *key, uint32_t len, trie_val_t **val); KR_EXPORT int trie_apply(trie_t *tbl, int (*f)(trie_val_t *, void *), void *d); +/*! + * \brief Apply a function to every trie_val_t, in order. + * + * It's like trie_apply() but additionally passes keys and their lengths. + * + * \param d Parameter passed as the second argument to f(). + * \return First nonzero from f() or zero (i.e. KNOT_EOK). + */ +KR_EXPORT +int trie_apply_with_key(trie_t *tbl, int (*f)(const char *, uint32_t, trie_val_t *, void *), void *d); + /*! * \brief Remove an item, returning KNOT_EOK if succeeded or KNOT_ENOENT if not found. *