The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
htrie.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/** hash / rb / patricia trees
18 *
19 * @file src/lib/util/htrie.c
20 *
21 * @copyright 2021 Network RADIUS SAS (legal@networkradius.com)
22 */
23RCSID("$Id: 1c1e9b75fc68a6e073f3e052bc933ccb518ebc38 $")
24
25#include <freeradius-devel/util/debug.h>
26#include <freeradius-devel/util/htrie.h>
27
28#define FUNC(_prefix, _op) ._op = (fr_htrie_ ##_op ## _t) fr_##_prefix##_## _op
29
31 { L("auto"), FR_HTRIE_AUTO },
32 { L("hash"), FR_HTRIE_HASH },
33 { L("rb"), FR_HTRIE_RB },
34 { L("trie"), FR_HTRIE_TRIE },
35};
37
39 [FR_HTRIE_HASH] = {
41 FUNC(hash_table, find),
42 FUNC(hash_table, insert),
43 FUNC(hash_table, replace),
44 FUNC(hash_table, remove),
45 FUNC(hash_table, delete),
46 FUNC(hash_table, num_elements),
49 },
50 [FR_HTRIE_RB] = {
51 .match = (fr_htrie_find_t) fr_rb_find,
52 FUNC(rb, find),
53 FUNC(rb, insert),
54 FUNC(rb, replace),
55 FUNC(rb, remove),
56 FUNC(rb, delete),
57 FUNC(rb, num_elements),
60 },
61 [FR_HTRIE_TRIE] = {
63 FUNC(trie, find),
64 FUNC(trie, insert),
65 FUNC(trie, replace),
66 FUNC(trie, remove),
67 FUNC(trie, delete),
68 FUNC(trie, num_elements),
69 }
70};
71
72/** An abstraction over our internal hashes, rb trees, and prefix tries
73 *
74 * This is useful where the data type being inserted into the tree
75 * is user controlled, and so we need to pick the most efficient structure
76 * for a given data type dynamically at runtime.
77 *
78 * @param[in] ctx to bind the htrie's lifetime to.
79 * @param[in] type One of:
80 * - FR_HTRIE_HASH
81 * - FR_HTRIE_RB
82 * - FR_HTRIE_TRIE
83 * @param[in] hash_data Used by FR_HTRIE_HASH to convert the
84 * data into a 32bit integer used for binning.
85 * @param[in] cmp_data Used to determine exact matched.
86 * @param[in] get_key Used by the prefix trie to extract a key
87 * from the data.
88 * @param[in] free_data The callback used to free the data if it is
89 * deleted or replaced. May be NULL in which
90 * case data will not be freed for these operations.
91 * @return
92 * - A new htrie on success.
93 * - NULL on failure, either missing functions or a memory allocation error.
94 */
95fr_htrie_t *fr_htrie_alloc(TALLOC_CTX *ctx,
97 fr_hash_t hash_data,
98 fr_cmp_t cmp_data,
99 fr_trie_key_t get_key,
100 fr_free_t free_data)
101{
102 fr_htrie_t *ht;
103
104 ht = talloc_zero(ctx, fr_htrie_t);
105 if (unlikely(!ht)) {
106 fr_strerror_const("Failed allocating fr_htrie_t");
107 return NULL;
108 }
109 ht->type = type;
110
111 switch (type) {
112 case FR_HTRIE_HASH:
113 if (!hash_data || !cmp_data) {
114 fr_strerror_const("hash_data and cmp_data must not be NULL for FR_HTRIE_HASH");
115 return NULL;
116 }
117
118 ht->store = fr_hash_table_alloc(ht, hash_data, cmp_data, free_data);
119 if (unlikely(!ht->store)) {
120 error:
121 talloc_free(ht);
122 return NULL;
123 }
124 ht->funcs = default_funcs[type];
125 return ht;
126
127 case FR_HTRIE_RB:
128 if (!cmp_data) {
129 fr_strerror_const("cmp_data must not be NULL for FR_HTRIE_RB");
130 return NULL;
131 }
132
133 ht->store = fr_rb_alloc(ht, cmp_data, free_data);
134 if (unlikely(!ht->store)) goto error;
135 ht->funcs = default_funcs[type];
136 return ht;
137
138 case FR_HTRIE_TRIE:
139 if (!get_key) {
140 fr_strerror_const("get_key must not be NULL for FR_HTRIE_TRIE");
141 return NULL;
142 }
143
144 ht->store = fr_trie_alloc(ht, get_key, free_data);
145 if (unlikely(!ht->store)) goto error;
146 ht->funcs = default_funcs[type];
147 return ht;
148
149 case FR_HTRIE_INVALID:
150 fr_assert_msg(0, "FR_TYPE_INVALID passed as htype");
151 return NULL;
152
153 case FR_HTRIE_AUTO:
154 fr_assert_msg(0, "FR_HTRIE_AUTO must be resolved to a concrete htype value using fr_htrie_hint()");
155 return NULL;
156
157 default:
158 return NULL;
159 }
160}
#define RCSID(id)
Definition build.h:487
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define unlikely(_x)
Definition build.h:383
#define NUM_ELEMENTS(_t)
Definition build.h:339
#define fr_assert_msg(_x, _msg,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
Definition debug.h:202
void * fr_hash_table_iter_next(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Iterate over entries in a hash table.
Definition hash.c:627
void * fr_hash_table_find(fr_hash_table_t *ht, void const *data)
Find data in a hash table.
Definition hash.c:430
void * fr_hash_table_iter_init(fr_hash_table_t *ht, fr_hash_iter_t *iter)
Initialise an iterator.
Definition hash.c:682
uint32_t(* fr_hash_t)(void const *)
Definition hash.h:36
#define fr_hash_table_alloc(_ctx, _hash_node, _cmp_node, _free_node)
Definition hash.h:61
talloc_free(hp)
static fr_htrie_funcs_t const default_funcs[]
Definition htrie.c:38
size_t fr_htrie_type_table_len
Definition htrie.c:36
fr_table_num_sorted_t const fr_htrie_type_table[]
Definition htrie.c:30
#define FUNC(_prefix, _op)
Definition htrie.c:28
fr_htrie_t * fr_htrie_alloc(TALLOC_CTX *ctx, fr_htrie_type_t type, fr_hash_t hash_data, fr_cmp_t cmp_data, fr_trie_key_t get_key, fr_free_t free_data)
An abstraction over our internal hashes, rb trees, and prefix tries.
Definition htrie.c:95
fr_htrie_type_t
Definition htrie.h:58
@ FR_HTRIE_RB
Data is stored in a rb tree.
Definition htrie.h:61
@ FR_HTRIE_TRIE
Data is stored in a prefix trie.
Definition htrie.h:62
@ FR_HTRIE_HASH
Data is stored in a hash.
Definition htrie.h:60
@ FR_HTRIE_AUTO
Automatically choose the best type.
Definition htrie.h:63
@ FR_HTRIE_INVALID
Definition htrie.h:59
void *(* fr_htrie_find_t)(void *ht, void const *data)
Definition htrie.h:37
void * store
What we're using to store node data.
Definition htrie.h:93
void *(* fr_htrie_iter_func_t)(void *ht, void *iter)
Definition htrie.h:56
fr_htrie_type_t type
type of the htrie
Definition htrie.h:92
fr_htrie_find_t match
exact prefix match
Definition htrie.h:78
fr_htrie_funcs_t funcs
Function pointers for the various operations.
Definition htrie.h:94
Which functions are used for the different operations.
Definition htrie.h:76
A hash/rb/prefix trie abstraction.
Definition htrie.h:91
int8_t(* fr_cmp_t)(void const *a, void const *b)
Definition misc.h:38
void(* fr_free_t)(void *)
Definition misc.h:39
void * fr_rb_iter_init_inorder(fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Initialise an in-order iterator.
Definition rb.c:824
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
Definition rb.c:577
void * fr_rb_iter_next_inorder(UNUSED fr_rb_tree_t *tree, fr_rb_iter_inorder_t *iter)
Return the next node.
Definition rb.c:850
#define fr_rb_alloc(_ctx, _data_cmp, _data_free)
Allocs a red black tree.
Definition rb.h:223
fr_aka_sim_id_type_t type
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
fr_trie_t * fr_trie_alloc(TALLOC_CTX *ctx, fr_trie_key_t get_key, fr_free_t free_data)
Allocate a trie.
Definition trie.c:741
void * fr_trie_match(fr_trie_t *ft, void const *data)
Match an element exactly in the trie, returning the data.
Definition trie.c:2668
int(* fr_trie_key_t)(uint8_t **out, size_t *outlen, void const *data)
Definition trie.h:56
#define fr_strerror_const(_msg)
Definition strerror.h:223