The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
htrie.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /** Structures and prototypes for hash / rbtree / patricia trie structures
19  *
20  * @file src/lib/util/htrie.h
21  *
22  * @copyright 2021 The FreeRADIUS server project
23  */
24 RCSIDH(htrie_h, "$Id: 06407e295505747b2528e67e686ed46dd7e6e015 $")
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <freeradius-devel/util/hash.h>
31 #include <freeradius-devel/util/rb.h>
32 #include <freeradius-devel/util/trie.h>
33 #include <freeradius-devel/util/types.h>
34 
35 typedef struct fr_htrie_s fr_htrie_t;
36 
37 typedef void *(*fr_htrie_find_t)(fr_htrie_t *ht, void const *data);
38 
39 typedef bool (*fr_htrie_insert_t)(fr_htrie_t *ht, void const *data);
40 
41 typedef int (*fr_htrie_replace_t)(void **old, fr_htrie_t *ht, void const *data);
42 
43 typedef void *(*fr_htrie_remove_t)(fr_htrie_t *ht, void const *data);
44 
45 typedef bool (*fr_htrie_delete_t)(fr_htrie_t *ht, void const *data);
46 
48 
49 typedef enum {
51  FR_HTRIE_HASH, //!< Data is stored in a hash.
52  FR_HTRIE_RB, //!< Data is stored in a rb tree.
53  FR_HTRIE_TRIE, //!< Data is stored in a prefix trie.
54  FR_HTRIE_AUTO, //!< Automatically choose the best type.
55  ///< Must be not be passed to fr_htrie_alloc().
56  ///< If the user selects this, you must
57  ///< call fr_htrie_hint() to determine the
58  ///< best type.
60 
62 extern size_t fr_htrie_type_table_len;
63 
64 /** Which functions are used for the different operations
65  *
66  */
67 typedef struct {
68  fr_htrie_find_t find; //!< Absolute or prefix match.
69  fr_htrie_find_t match; //!< exact prefix match
70  fr_htrie_insert_t insert; //!< Insert a new item into the store.
71  fr_htrie_replace_t replace; //!< Replace an existing item in store.
72  fr_htrie_remove_t remove; //!< Remove an item from the store.
73  fr_htrie_delete_t delete; //!< Remove (and possibly free) and item from the store.
74  fr_htrie_num_elements_t num_elements; //!< Number of elements currently in the store.
76 
77 /** A hash/rb/prefix trie abstraction
78  *
79  */
80 struct fr_htrie_s {
81  fr_htrie_type_t type; //!< type of the htrie
82  void *store; //!< What we're using to store node data
83  fr_htrie_funcs_t funcs; //!< Function pointers for the various operations.
84 };
85 
86 fr_htrie_t *fr_htrie_alloc(TALLOC_CTX *ctx,
88  fr_hash_t hash_data,
89  fr_cmp_t cmp_data,
90  fr_trie_key_t get_key,
91  fr_free_t free_data);
92 
93 /** Match data in a htrie
94  *
95  */
96 static inline CC_HINT(nonnull) void *fr_htrie_match(fr_htrie_t *ht, void const *data)
97 {
98  return ht->funcs.match(ht->store, data);
99 }
100 
101 /** Find data in a htrie
102  *
103  */
104 static inline CC_HINT(nonnull) void *fr_htrie_find(fr_htrie_t *ht, void const *data)
105 {
106  return ht->funcs.find(ht->store, data);
107 }
108 
109 /** Insert data into a htrie
110  *
111  */
112 static inline CC_HINT(nonnull) bool fr_htrie_insert(fr_htrie_t *ht, void const *data)
113 {
114  return ht->funcs.insert(ht->store, data);
115 }
116 
117 /** Replace data in a htrie, freeing previous data if free_data cb was passed to fr_htrie_alloc
118  *
119  */
120 static inline CC_HINT(nonnull(2,3)) int fr_htrie_replace(void **old, fr_htrie_t *ht, void const *data)
121 {
122  return ht->funcs.replace(old, ht->store, data);
123 }
124 
125 /** Remove data from a htrie without freeing it
126  *
127  */
128 static inline CC_HINT(nonnull) void *fr_htrie_remove(fr_htrie_t *ht, void const *data)
129 {
130  return ht->funcs.remove(ht->store, data);
131 }
132 
133 /** Delete data from a htrie, freeing it if free_data cb was passed to fr_htrie_alloc
134  *
135  */
136 static inline CC_HINT(nonnull) bool fr_htrie_delete(fr_htrie_t *ht, void const *data)
137 {
138  return ht->funcs.delete(ht->store, data);
139 }
140 
141 /** Return the number of elements in the htrie
142  *
143  */
144 static inline CC_HINT(nonnull) int fr_htrie_num_elements(fr_htrie_t *ht)
145 {
146  return ht->funcs.num_elements(ht->store);
147 }
148 
150 {
151  switch (type) {
152  case FR_TYPE_STRING:
153  case FR_TYPE_OCTETS:
154  return FR_HTRIE_HASH;
155 
156  /* IPv4/v6 IP and prefix */
157  case FR_TYPE_IP:
158  return FR_HTRIE_TRIE;
159 
160  case FR_TYPE_IFID:
161  case FR_TYPE_ETHERNET:
162  case FR_TYPE_INTEGER:
163  case FR_TYPE_FLOAT32:
164  case FR_TYPE_FLOAT64:
165  return FR_HTRIE_RB;
166 
167  case FR_TYPE_VOID:
168  case FR_TYPE_NULL:
169  case FR_TYPE_VALUE_BOX:
170  case FR_TYPE_STRUCTURAL:
171  case FR_TYPE_MAX:
172  break;
173  }
174 
175  return FR_HTRIE_INVALID;
176 }
177 
178 /** Return a static string containing the type name
179  *
180  * @param[in] type to return name for.
181  * @return name of the type
182  *
183  * @hidecallergraph
184  */
185 static inline char const *fr_htrie_type_to_str(fr_htrie_type_t type)
186 {
187  return fr_table_str_by_value(fr_htrie_type_table, type, "<INVALID>");
188 }
189 
190 #ifdef __cplusplus
191 }
192 #endif
#define RCSIDH(h, id)
Definition: build.h:445
uint32_t(* fr_hash_t)(void const *)
Definition: hash.h:36
int(* fr_htrie_replace_t)(void **old, fr_htrie_t *ht, void const *data)
Definition: htrie.h:41
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
static fr_htrie_type_t fr_htrie_hint(fr_type_t type)
Definition: htrie.h:149
static void * fr_htrie_match(fr_htrie_t *ht, void const *data)
Match data in a htrie.
Definition: htrie.h:96
fr_htrie_find_t find
Absolute or prefix match.
Definition: htrie.h:68
static bool fr_htrie_insert(fr_htrie_t *ht, void const *data)
Insert data into a htrie.
Definition: htrie.h:112
uint32_t(* fr_htrie_num_elements_t)(fr_htrie_t *ht)
Definition: htrie.h:47
bool(* fr_htrie_insert_t)(fr_htrie_t *ht, void const *data)
Definition: htrie.h:39
static int fr_htrie_num_elements(fr_htrie_t *ht)
Return the number of elements in the htrie.
Definition: htrie.h:144
void * store
What we're using to store node data.
Definition: htrie.h:82
fr_htrie_replace_t replace
Replace an existing item in store.
Definition: htrie.h:71
static bool fr_htrie_delete(fr_htrie_t *ht, void const *data)
Delete data from a htrie, freeing it if free_data cb was passed to fr_htrie_alloc.
Definition: htrie.h:136
fr_htrie_type_t type
type of the htrie
Definition: htrie.h:81
static int fr_htrie_replace(void **old, fr_htrie_t *ht, void const *data)
Replace data in a htrie, freeing previous data if free_data cb was passed to fr_htrie_alloc.
Definition: htrie.h:120
size_t fr_htrie_type_table_len
Definition: htrie.c:37
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_table_num_sorted_t const fr_htrie_type_table[]
Definition: htrie.c:31
fr_htrie_delete_t delete
Remove (and possibly free) and item from the store.
Definition: htrie.h:73
static void * fr_htrie_remove(fr_htrie_t *ht, void const *data)
Remove data from a htrie without freeing it.
Definition: htrie.h:128
static void * fr_htrie_find(fr_htrie_t *ht, void const *data)
Find data in a htrie.
Definition: htrie.h:104
fr_htrie_find_t match
exact prefix match
Definition: htrie.h:69
void *(* fr_htrie_remove_t)(fr_htrie_t *ht, void const *data)
Definition: htrie.h:43
bool(* fr_htrie_delete_t)(fr_htrie_t *ht, void const *data)
Definition: htrie.h:45
fr_htrie_funcs_t funcs
Function pointers for the various operations.
Definition: htrie.h:83
fr_htrie_remove_t remove
Remove an item from the store.
Definition: htrie.h:72
fr_htrie_num_elements_t num_elements
Number of elements currently in the store.
Definition: htrie.h:74
static char const * fr_htrie_type_to_str(fr_htrie_type_t type)
Return a static string containing the type name.
Definition: htrie.h:185
fr_htrie_insert_t insert
Insert a new item into the store.
Definition: htrie.h:70
void *(* fr_htrie_find_t)(fr_htrie_t *ht, void const *data)
Definition: htrie.h:37
Which functions are used for the different operations.
Definition: htrie.h:67
A hash/rb/prefix trie abstraction.
Definition: htrie.h:80
fr_type_t
Definition: merged_model.c:80
@ FR_TYPE_FLOAT32
Single precision floating point.
Definition: merged_model.c:108
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
Definition: merged_model.c:93
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_MAX
Number of defined data types.
Definition: merged_model.c:130
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
Definition: merged_model.c:81
@ FR_TYPE_VALUE_BOX
A boxed value.
Definition: merged_model.c:125
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_IFID
Interface ID.
Definition: merged_model.c:90
@ FR_TYPE_OCTETS
Raw octets.
Definition: merged_model.c:84
@ FR_TYPE_FLOAT64
Double precision floating point.
Definition: merged_model.c:109
unsigned int uint32_t
Definition: merged_model.c:33
unsigned char bool
Definition: merged_model.c:19
int8_t(* fr_cmp_t)(void const *a, void const *b)
Definition: misc.h:38
void(* fr_free_t)(void *)
Definition: misc.h:39
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition: table.h:253
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:45
int(* fr_trie_key_t)(uint8_t **out, size_t *outlen, void const *data)
Definition: trie.h:56
#define FR_TYPE_STRUCTURAL
Definition: types.h:296
#define FR_TYPE_IP
Definition: types.h:288
#define FR_TYPE_INTEGER
Definition: types.h:284
static fr_slen_t data
Definition: value.h:1259
int nonnull(2, 5))