1 | /***************************************
2 | $Revision: 1.9 $
3 |
4 | Radix tree (rx). rxroutines.h - header file for radix tree handling module.
5 |
6 | Status: NOT REVUED, TESTED
7 |
8 | Design and implementation by: marek
9 |
10 | ******************/ /******************
11 | Copyright (c) 1999 RIPE NCC
12 |
13 | All Rights Reserved
14 |
15 | Permission to use, copy, modify, and distribute this software and its
16 | documentation for any purpose and without fee is hereby granted,
17 | provided that the above copyright notice appear in all copies and that
18 | both that copyright notice and this permission notice appear in
19 | supporting documentation, and that the name of the author not be
20 | used in advertising or publicity pertaining to distribution of the
21 | software without specific, written prior permission.
22 |
23 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
24 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
25 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
26 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 | ***************************************/
30 |
31 | #ifndef _RX_H
32 | #define _RX_H
33 |
34 | #include <glib.h>
35 | #ifndef G_THREADS_ENABLED
36 | #error "GLib must be compiled with thread support enabled to be MT-Safe"
37 | #endif
38 |
39 | #include <pthread.h>
40 | #include <stubs.h>
41 |
42 | #include <memwrap.h>
43 | #include <stdio.h>
44 | #include <iproutines.h>
45 |
46 | #include <rx_globals.h>
47 |
48 | typedef int rx_regid_t;
49 |
50 | typedef enum {
51 | RX_FAM_RT = 1,
52 | RX_FAM_IN,
53 | RX_FAM_BOTH /*+ used only in asc_search, meaningless otherwise
54 | Relies on the fact that 1+2=3 :-) (bitmask) +*/
55 | } rx_fam_t;
56 |
57 | /*+ the node operation modes +*/
58 | typedef enum {
59 | RX_OPER_CRE = 1,
60 | RX_OPER_MOD,
61 | RX_OPER_DEL
62 | } rx_oper_mt;
63 |
64 |
65 | /*+ stack building modes +*/
66 | typedef enum {
67 | RX_STK_CREAT = 1, /*+ - creation = all glue nodes, stop at first non-glue +*/
68 | RX_STK_QUERY_ALLNOD, /*+ - query = all glue nodes, stop when deep enough */
69 | RX_STK_QUERY_NOGLUE /*+ - query = no glue nodes, stop when deep enough */
70 | } rx_stk_mt;
71 |
72 | /*+ the search modes +*/
73 | typedef enum {
74 | RX_SRCH_CREAT = 1, /*+ special search - does not skip glue nodes +*/
75 | RX_SRCH_EXLESS, /*+ the default search +*/
76 | RX_SRCH_EXACT,
77 | RX_SRCH_LESS,
78 | RX_SRCH_MORE, /*+ more specific search +*/
79 | RX_SRCH_DBLS, /*+ special more spec: return only nodes with
80 | more than one data leaves +*/
81 | RX_SRCH_RANG /*+ more specific range search, RPSL style : ^n-m +*/
82 | } rx_srch_mt;
83 |
84 |
85 | // constant to mean 'unlimited number of answers from a search'
86 | #define RX_ANS_ALL (-1)
87 |
88 | #define RX_ALL_DEPTHS 255
89 |
90 |
91 | /*+ radix tree's memory modes -- not yet implemented +*/
92 | typedef enum {
93 | RX_MEM_RAMONLY,
94 | RX_MEM_RAMSQL,
95 | RX_MEM_SQLONLY
96 | } rx_mem_mt;
97 |
98 |
99 |
100 | /*+ subtree modes -- not yet implemented +*/
101 | typedef enum {
102 | RX_SUB_NONE,
103 | RX_SUB_AUTO,
104 | RX_SUB_HAND
105 | } rx_subtree_mt;
106 |
107 | /* modes for tree traversal (walk_tree) */
108 | typedef enum {
109 | RX_WALK_CNTGLU=1, /*+ default: count also glue nodes and make the level
110 | checking aware of them +*/
111 |
112 | RX_WALK_SKPGLU=2, /*+ only real nodes counted & watched in level checks +*/
113 |
114 | RX_WALK_PRFLEN=4, /*+ make level check a check for prefix length;
115 | still only non-glue nodes are counted +*/
116 | RX_WALK_REVERS=8 /*+ reverse the order of traversing the tree
117 | (first link 1 then 0) +*/
118 | } rx_walk_mt;
119 |
120 |
121 | /*+ A struct for data hooked via a double linked list at a radix node.
122 | Must uniquely define the object for lookups in the SQL tables and/or memory.
123 | Must also contain enough info to let the delete_node choose (and remove)
124 | the proper object from the (linked) list +*/
125 |
126 | typedef struct {
127 | ip_range_t iprange; /*+ for inetnums. empty for routes +*/
128 |
129 | char composed; /*+ flag; non-zero for composed inetnums +*/
130 |
131 | void *data_ptr; /*+ to in-memory immediate data +*/
132 | int data_len; /*+ and its length +*/
133 |
134 | sql_key_t data_key; /*+ key to the SQL full-text data record +*/
135 | sql_key_t leaf_key; /*+ pointer to the SQL data leaf record +*/
136 | } rx_dataleaf_t;
137 |
138 | /*+
139 | The struct for radix nodes.
140 |
141 | Must contain prefix, parent, left/right child links in memory and sql,
142 | link to the sql version of the node.
143 | And of course data: pointer to a double linked list of rx_data_t's.
144 | +*/
145 |
146 | typedef struct _rx_node_str {
147 | ip_prefix_t prefix; /*+ who am i. +*/
148 |
149 | char glue;
150 | /*+ now this is an indicator for a node that it
151 | is not holding a real prefix,
152 | but is only a glue node +*/
153 |
154 | GList *leaves_ptr; /*+ a double-linked list of rx_data_t structs
155 | the data leaves can be multiple at each node
156 | (due to a user error the inetnum ranges can
157 | overlap, due to multihoming or error routes
158 | can be duplicated ).
159 | So we link a dynamic thing here +*/
160 |
161 | // sql_key_t leaves_key;
162 | /* "linked list" not needed in sql -
163 | the data leaves can be found in node_leaf
164 | table as those that have
165 | node_key in node_id */
166 |
167 | struct _rx_node_str
168 | *parent_ptr, /*+ radix links in memory +*/
169 | *child_ptr[2]; /*+ NULL means empty +*/
170 |
171 | sql_key_t parent_key, /*+ radix links in SQL +*/
172 | child_key[2]; /*+ zero means empty +*/
173 |
174 | sql_key_t node_key; /*+ key of the corresponding SQL radix node +*/
175 |
176 | } rx_node_t;
177 |
178 |
179 | /*+
180 | rx_tree_t - defines a radix tree.
181 |
182 | includes a pointer(key) to the top node,
183 |
184 | names of the corresponding SQL tables
185 | (they can be generated automatically,
186 | but this is the place to store the result)
187 | Data_table is for data_key.
188 | Radix_table is for parent_id, right_id, left_id, node_id.
189 | Leaves_table is for leaves_key (double linked list in SQL).
190 | +*/
191 |
192 | typedef struct _rx_tree_str {
193 | rx_regid_t reg_id; /*+ registry id +*/
194 | ip_space_t space; /*+ one of IPv4, IPv6 +*/
195 | rx_fam_t family; /*+ one of RT, IN +*/
196 |
197 | rx_subtree_mt subtrees; /*+ one of NONE, AUTO, HAND +*/
198 | rx_mem_mt mem_mode; /*+ where the tree will sit - SQL or RAM +*/
199 | struct rx_tree_str
200 | *parent_tree; /*+ pointer to the parent tree +*/
201 |
202 | ip_prefix_t prefix; /*+ of the IP space this tree covers +*/
203 |
204 | int maxbits; /*+ max depth of this tree
205 | (depends on the space, so it is redundant)+*/
206 | sql_tblnam_t data_table;
207 | sql_tblnam_t radix_table;
208 | sql_tblnam_t leaves_table;
209 |
210 | int num_nodes; /*+ number of nodes in tree - for assertions +*/
211 |
212 | rx_node_t *top_ptr; /*+ pointer to the top node +*/
213 | long top_key; /*+ the same in SQL +*/
214 |
215 | pthread_mutex_t mutex; /*+ per-tree mutex +*/
216 |
217 | } rx_tree_t;
218 |
219 |
220 | /*+ this is a definition of a node copy used for:
221 |
222 | * stack elements returned from rx_stack_build,
223 |
224 | * answer elements from an rx_nod_search.
225 |
226 | It *must* hold pointers to the original locations of it (in terms of
227 | memory and SQL) so that one could actually modify the node...
228 | In SQL tree mode it holds also a copy of a node.
229 | This seems to be unnecessary for in-memory radix trees but is a must
230 | for sql ones.
231 |
232 | WARNING!!!!! The fact that pointers to tree and memory / SQL nodes are
233 | here is a subject to race condition. The location of the tree in the
234 | forest list and the node in memory must not change.
235 |
236 | +*/
237 |
238 | typedef struct {
239 | rx_tree_t *tree; /*+ contains registry_id, space_id, sql table names +*/
240 | rx_node_t *srcptr;
241 | sql_key_t srckey;
242 | rx_node_t cpy; /*+ filled in if the tree is kept in SQL only mode +*/
243 | } rx_nodcpy_t;
244 |
245 |
246 | /*+
247 | This represents one data leaf (by reference). It's used for returning data
248 | from rx_bin_search() to rx_asc_search().
249 | +*/
250 | typedef struct {
251 | sql_key_t srckey;
252 | rx_dataleaf_t *leafptr;
253 | } rx_datref_t;
254 |
255 |
256 | /*+ this is a structure used for returning the data from the search.
257 | It contains a copy of the dataleaf and a pointer to the source +*/
258 | typedef struct {
259 | sql_key_t srckey;
260 | rx_dataleaf_t leafcpy;
261 | } rx_datcpy_t;
262 |
263 | /*
264 | * -----------------------------------------------------------------------
265 | *
266 | * now, THIS is a scrap heap for things that MAY BE useful
267 | */
268 |
269 | /* a definite pointer to an sql object: table name + key
270 | However, it might be nice to include the table TYPE so that one knows
271 | what data it holds :-)
272 | */
273 | typedef struct {
274 | sql_tblnam_t name;
275 | sql_key_t key;
276 | } rx_sqlobj_t;
277 |
278 |
279 | typedef struct {
280 | GList **nodlist;
281 | rx_tree_t *tree;
282 | ip_prefix_t *prefix;
283 | } hook_addnode_userdat_t;
284 |
285 | /********************* P R O T O T Y P E S **********************/
286 |
287 |
288 | void rx_free_list_element(void *cpy, void *trash);
289 |
290 | er_ret_t
291 | RX_space_cre (
292 | rx_regid_t reg_id,
293 | ip_space_t spc_id,
294 | rx_fam_t fam_id,
295 | char *prefixstr,
296 | rx_mem_mt mem_mode, // memory only, memory+sql, sql only
297 | rx_subtree_mt subtrees // NONE, AUTO, HAND
298 | );
299 | er_ret_t
300 | RX_get_tree ( rx_tree_t **treeptr,
301 | rx_regid_t reg_id,
302 | ip_space_t spc_id,
303 | rx_fam_t fam_id
304 | );
305 |
306 | er_ret_t
307 | rx_build_stack(rx_nodcpy_t stack[],
308 | int *maxdepth,
309 | rx_tree_t *tree,
310 | ip_prefix_t *newpref,
311 | rx_stk_mt dmode
312 | );
313 |
314 | er_ret_t
315 | rx_nod_search (
316 | rx_srch_mt search_mode,
317 | int par_a,
318 | int par_b,
319 | /* see rx_asc_search() for explanation */
320 | rx_tree_t *tree, // tree ptr
321 | ip_prefix_t *prefix, // binary prefix
322 |
323 | rx_nodcpy_t stack[], // stack==array of node_copies
324 | int stackcount, // number of element on the stack,
325 | // can come from a creat stack!
326 |
327 | GList **nodlist, // answers go here
328 | int max_count // max # of answers
329 | );
330 | int
331 | rx_walk_tree(rx_node_t *node,
332 | er_ret_t (*func)(rx_node_t *node, int level, int nodecounter,
333 | void *userptr),
334 | rx_walk_mt walk_mode,
335 | int maxlevel,
336 | int level,
337 | int nodecounter,
338 | void *userptr,
339 | er_ret_t *err);
340 |
341 | er_ret_t rx_tree_print( rx_tree_t *tree );
342 | void rx_space_list(void);
343 | void rx_nod_print( rx_node_t *node, char *buf, int maxchar );
344 | void rx_stk_print( rx_nodcpy_t stack[], int stackdepth );
345 |
346 | #undef EXTDEF
347 | #endif /* _RX_H */