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: efca3c5792829c563310161ae4feb280a12d3741 $")
24
25#include <freeradius-devel/util/debug.h>
26#include <freeradius-devel/util/htrie.h>
27#include <freeradius-devel/util/table.h>
28
29#define FUNC(_prefix, _op) ._op = (fr_htrie_ ##_op ## _t) fr_##_prefix##_## _op
30
32 { L("auto"), FR_HTRIE_AUTO },
33 { L("hash"), FR_HTRIE_HASH },
34 { L("rb"), FR_HTRIE_RB },
35 { L("trie"), FR_HTRIE_TRIE },
36};
38
40 [FR_HTRIE_HASH] = {
42 FUNC(hash_table, find),
43 FUNC(hash_table, insert),
44 FUNC(hash_table, replace),
45 FUNC(hash_table, remove),
46 FUNC(hash_table, delete),
47 FUNC(hash_table, num_elements)
48 },
49 [FR_HTRIE_RB] = {
50 .match = (fr_htrie_find_t) fr_rb_find,
51 FUNC(rb, find),
52 FUNC(rb, insert),
53 FUNC(rb, replace),
54 FUNC(rb, remove),
55 FUNC(rb, delete),
56 FUNC(rb, num_elements)
57 },
58 [FR_HTRIE_TRIE] = {
60 FUNC(trie, find),
61 FUNC(trie, insert),
62 FUNC(trie, replace),
63 FUNC(trie, remove),
64 FUNC(trie, delete),
65 FUNC(trie, num_elements)
66 }
67};
68
69/** An abstraction over our internal hashes, rb trees, and prefix tries
70 *
71 * This is useful where the data type being inserted into the tree
72 * is user controlled, and so we need to pick the most efficient structure
73 * for a given data type dynamically at runtime.
74 *
75 * @param[in] ctx to bind the htrie's lifetime to.
76 * @param[in] type One of:
77 * - FR_HTRIE_HASH
78 * - FR_HTRIE_RB
79 * - FR_HTRIE_TRIE
80 * @param[in] hash_data Used by FR_HTRIE_HASH to convert the
81 * data into a 32bit integer used for binning.
82 * @param[in] cmp_data Used to determine exact matched.
83 * @param[in] get_key Used by the prefix trie to extract a key
84 * from the data.
85 * @param[in] free_data The callback used to free the data if it is
86 * deleted or replaced. May be NULL in which
87 * case data will not be freed for these operations.
88 * @return
89 * - A new htrie on success.
90 * - NULL on failure, either missing functions or a memory allocation error.
91 */
92fr_htrie_t *fr_htrie_alloc(TALLOC_CTX *ctx,
94 fr_hash_t hash_data,
95 fr_cmp_t cmp_data,
96 fr_trie_key_t get_key,
97 fr_free_t free_data)
98{
99 fr_htrie_t *ht;
100
101 ht = talloc_zero(ctx, fr_htrie_t);
102 if (unlikely(!ht)) {
103 fr_strerror_const("Failed allocating fr_htrie_t");
104 return NULL;
105 }
106 ht->type = type;
107
108 switch (type) {
109 case FR_HTRIE_HASH:
110 if (!hash_data || !cmp_data) {
111 fr_strerror_const("hash_data and cmp_data must not be NULL for FR_HTRIE_HASH");
112 return NULL;
113 }
114
115 ht->store = fr_hash_table_alloc(ht, hash_data, cmp_data, free_data);
116 if (unlikely(!ht->store)) {
117 error:
118 talloc_free(ht);
119 return NULL;
120 }
121 ht->funcs = default_funcs[type];
122 return ht;
123
124 case FR_HTRIE_RB:
125 if (!cmp_data) {
126 fr_strerror_const("cmp_data must not be NULL for FR_HTRIE_RB");
127 return NULL;
128 }
129
130 ht->store = fr_rb_alloc(ht, cmp_data, free_data);
131 if (unlikely(!ht->store)) goto error;
132 ht->funcs = default_funcs[type];
133 return ht;
134
135 case FR_HTRIE_TRIE:
136 if (!get_key) {
137 fr_strerror_const("get_key must not be NULL for FR_HTRIE_TRIE");
138 return NULL;
139 }
140
141 ht->store = fr_trie_alloc(ht, get_key, free_data);
142 if (unlikely(!ht->store)) goto error;
143 ht->funcs = default_funcs[type];
144 return ht;
145
146 case FR_HTRIE_INVALID:
147 fr_assert_msg(0, "FR_TYPE_INVALID passed as htype");
148 return NULL;
149
150 case FR_HTRIE_AUTO:
151 fr_assert_msg(0, "FR_HTRIE_AUTO must be resolved to a concrete htype value using fr_htrie_hint()");
152 return NULL;
153
154 default:
155 return NULL;
156 }
157}
#define RCSID(id)
Definition build.h:483
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:209
#define unlikely(_x)
Definition build.h:381
#define NUM_ELEMENTS(_t)
Definition build.h:337
static fr_ring_buffer_t * rb
#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:210
void * fr_hash_table_find(fr_hash_table_t *ht, void const *data)
Find data in a hash table.
Definition hash.c:429
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:58
static fr_htrie_funcs_t const default_funcs[]
Definition htrie.c:39
size_t fr_htrie_type_table_len
Definition htrie.c:37
fr_table_num_sorted_t const fr_htrie_type_table[]
Definition htrie.c:31
#define FUNC(_prefix, _op)
Definition htrie.c:29
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:92
fr_htrie_type_t
Definition htrie.h:49
@ FR_HTRIE_RB
Data is stored in a rb tree.
Definition htrie.h:52
@ FR_HTRIE_TRIE
Data is stored in a prefix trie.
Definition htrie.h:53
@ FR_HTRIE_HASH
Data is stored in a hash.
Definition htrie.h:51
@ FR_HTRIE_AUTO
Automatically choose the best type.
Definition htrie.h:54
@ FR_HTRIE_INVALID
Definition htrie.h:50
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:82
fr_htrie_type_t type
type of the htrie
Definition htrie.h:81
fr_htrie_find_t match
exact prefix match
Definition htrie.h:69
fr_htrie_funcs_t funcs
Function pointers for the various operations.
Definition htrie.h:83
Which functions are used for the different operations.
Definition htrie.h:67
A hash/rb/prefix trie abstraction.
Definition htrie.h:80
talloc_free(reap)
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_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
#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