modules/rx/rxroutines.h
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
1 /***************************************
2 $Revision: 1.25 $
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 #include <erroutines.h>
46
47 #include "sk.h" /*condat*/
48
49 #include "thread.h" /*rwlock*/
50
51
52 typedef enum {
53 RX_FAM_RT = 1,
54 RX_FAM_IN = 2,
55 RX_FAM_IP = 4
56 } rx_fam_t;
57
58
59 /*+ the node operation modes +*/
60 typedef enum {
61 RX_OPER_CRE = 1,
62 RX_OPER_DEL
63 } rx_oper_mt;
64
65
66 /*+ stack building modes +*/
67 typedef enum {
68 RX_STK_CREAT = 1, /*+ - creation = all glue nodes, stop at first non-glue +*/
69 RX_STK_QUERY_ALLNOD, /*+ - query = all glue nodes, stop when deep enough */
70 RX_STK_QUERY_NOGLUE /*+ - query = no glue nodes, stop when deep enough */
71 } rx_stk_mt;
72
73 /*+ the search modes +*/
74 typedef enum {
75 RX_SRCH_CREAT = 1, /*+ special search - does not skip glue nodes +*/
76 RX_SRCH_EXLESS, /*+ the default search +*/
77 RX_SRCH_EXACT,
78 RX_SRCH_LESS,
79 RX_SRCH_MORE, /*+ more specific search +*/
80 RX_SRCH_DBLS, /*+ special more spec: return only nodes with
81 more than one data leaves +*/
82 RX_SRCH_RANG /*+ more specific range search, RPSL style : ^n-m +*/
83 } rx_srch_mt;
84
85
86 #ifdef RX_IMPL_PRINT
87 char *rx_srch_mode_text[]={
88 "", /* begins with 1 */
89 "CREAT",
90 "EXLESS",
91 "EXACT",
92 "LESS",
93 "MORE",
94 "DBLS",
95 "RANG"
96 };
97 #endif
98
99 /* constant to mean 'unlimited number of answers from a search' */
100 #define RX_ANS_ALL (-1)
101
102 #define RX_ALL_DEPTHS 255
103
104
105 /*+ radix tree's memory modes -- not yet implemented +*/
106 typedef enum {
107 RX_MEM_RAMONLY,
108 RX_MEM_RAMSQL,
109 RX_MEM_SQLONLY
110 } rx_mem_mt;
111
112
113
114 /*+ subtree modes -- not yet implemented +*/
115 typedef enum {
116 RX_SUB_NONE,
117 RX_SUB_AUTO,
118 RX_SUB_HAND
119 } rx_subtree_mt;
120
121 /* modes for tree traversal (walk_tree) */
122 typedef enum {
123 RX_WALK_CNTGLU=1, /*+ default: count also glue nodes and make the level
124 checking aware of them +*/
125
126 RX_WALK_SKPGLU=2, /*+ only real nodes counted & watched in level checks +*/
127
128 RX_WALK_PRFLEN=4, /*+ make level check a check for prefix length;
129 still only non-glue nodes are counted +*/
130 RX_WALK_REVERS=8 /*+ reverse the order of traversing the tree
131 (first link 1 then 0) +*/
132 } rx_walk_mt;
133
134
135 /*+ A struct for data hooked via a double linked list at a radix node.
136 Must uniquely define the object for lookups in the SQL tables and/or memory.
137 Must also contain enough info to let the delete_node choose (and remove)
138 the proper object from the (linked) list +*/
139
140 typedef struct {
141 ip_range_t iprange; /*+ filled for all trees. Used in rp_search
142 for determining exact matches (all trees)
143 and to see if an address is in range
144 (only IPv4 inetnum trees) +*/
145 unsigned char preflen; /* to avoid arithmetics on IPv6 ranges,
146 we have to store prefix length to
147 determine the shortest object in search.
148 This is filled in for all route trees
149 */
150
151 char composed; /*+ non-zero for composed inetnums
152 equal to: the number of prefixes composing
153 the range - minus 1 +*/
154
155 void *data_ptr; /*+ to in-memory immediate data +*/
156 unsigned data_len; /*+ and its length +*/
157
158 sql_key_t data_key; /*+ key to the SQL full-text data record +*/
159 sql_key_t leaf_key; /*+ pointer to the SQL data leaf record +*/
160 } rx_dataleaf_t;
161
162 /*+
163 The struct for radix nodes.
164
165 Must contain prefix, parent, left/right child links in memory and sql,
166 link to the sql version of the node.
167 And of course data: pointer to a double linked list of rx_data_t's.
168 +*/
169
170 typedef struct _rx_node_str {
171 ip_prefix_t prefix; /*+ who am i. +*/
172
173 char glue;
174 /*+ now this is an indicator for a node that it
175 is not holding a real prefix,
176 but is only a glue node +*/
177
178 GList *leaves_ptr; /*+ a double-linked list of rx_data_t structs
179 the data leaves can be multiple at each node
180 (due to a user error the inetnum ranges can
181 overlap, due to multihoming or error routes
182 can be duplicated ).
183 So we link a dynamic thing here +*/
184
185 /* sql_key_t leaves_key; */
186 /* "linked list" not needed in sql -
187 the data leaves can be found in node_leaf
188 table as those that have
189 node_key in node_id */
190
191 struct _rx_node_str
192 *parent_ptr, /*+ radix links in memory +*/
193 *child_ptr[2]; /*+ NULL means empty +*/
194
195 sql_key_t parent_key, /*+ radix links in SQL +*/
196 child_key[2]; /*+ zero means empty +*/
197
198 sql_key_t node_key; /*+ key of the corresponding SQL radix node +*/
199
200 } rx_node_t;
201
202
203 /*+
204 rx_tree_t - defines a radix tree.
205
206 includes a pointer(key) to the top node,
207
208 names of the corresponding SQL tables
209 (they can be generated automatically,
210 but this is the place to store the result)
211 Data_table is for data_key.
212 Radix_table is for parent_id, right_id, left_id, node_id.
213 Leaves_table is for leaves_key (double linked list in SQL).
214 +*/
215
216 typedef struct _rx_tree_str {
217 ip_space_t space; /*+ one of IPv4, IPv6 +*/
218 rx_fam_t family; /*+ one of RT, IN +*/
219
220 rx_subtree_mt subtrees; /*+ one of NONE, AUTO, HAND +*/
221 rx_mem_mt mem_mode; /*+ where the tree will sit - SQL or RAM +*/
222 struct rx_tree_str
223 *parent_tree; /*+ pointer to the parent tree +*/
224
225 ip_prefix_t prefix; /*+ of the IP space this tree covers +*/
226
227 int maxbits; /*+ max depth of this tree
228 (depends on the space, so it is redundant)+*/
229 sql_tblnam_t data_table;
230 sql_tblnam_t radix_table;
231 sql_tblnam_t leaves_table;
232
233 int num_nodes; /*+ number of nodes in tree - for assertions +*/
234
235 rx_node_t *top_ptr; /*+ pointer to the top node +*/
236 long top_key; /*+ the same in SQL +*/
237
238 rw_lock_t rwlock; /*+ per-tree reader/writer lock +*/
239
240 } rx_tree_t;
241
242
243 /*+ this is a definition of a node copy used for:
244
245 * stack elements returned from rx_stack_build,
246
247 * answer elements from an rx_nod_search.
248
249 It *must* hold pointers to the original locations of it (in terms of
250 memory and SQL) so that one could actually modify the node...
251 In SQL tree mode it holds also a copy of a node.
252 This seems to be unnecessary for in-memory radix trees but is a must
253 for sql ones.
254
255 WARNING!!!!! The fact that pointers to tree and memory / SQL nodes are
256 here is a subject to race condition. The location of the tree in the
257 forest list and the node in memory must not change.
258
259 +*/
260
261 typedef struct {
262 rx_tree_t *tree; /*+ contains registry_id, space_id, sql table names +*/
263 rx_node_t *srcptr;
264 sql_key_t srckey;
265 rx_node_t cpy; /*+ filled in if the tree is kept in SQL only mode +*/
266 } rx_nodcpy_t;
267
268
269 /*+
270 This represents one data leaf (by reference). It's used for returning data
271 from rx_bin_search() to rx_asc_search().
272 +*/
273 typedef struct {
274 sql_key_t srckey;
275 rx_dataleaf_t *leafptr;
276 } rx_datref_t;
277
278
279 /*+ this is a structure used for returning the data from the search.
280 It contains a copy of the dataleaf and a pointer to the source +*/
281 typedef struct {
282 sql_key_t srckey;
283 rx_dataleaf_t leafcpy;
284 } rx_datcpy_t;
285
286 typedef struct {
287 rx_node_t *node;
288 int code;
289 int datatoo;
290 rx_tree_t *tree;
291 } rx_treecheck_t;
292
293 /*
294 * -----------------------------------------------------------------------
295 *
296 * now, THIS is a scrap heap for things that MAY BE useful
297 */
298
299 /* a definite pointer to an sql object: table name + key
300 However, it might be nice to include the table TYPE so that one knows
301 what data it holds :-)
302 */
303 typedef struct {
304 sql_tblnam_t name;
305 sql_key_t key;
306 } rx_sqlobj_t;
307
308
309 typedef struct {
310 GList **nodlist;
311 rx_tree_t *tree;
312 ip_prefix_t *prefix;
313 } hook_addnode_userdat_t;
314
315 /********************* P R O T O T Y P E S **********************/
316
317
318 void rx_free_list_element(void *cpy, void *trash);
319
320
321
322 er_ret_t
323 RX_treecheck( rx_tree_t *tree, int datatoo, rx_treecheck_t *errorfound);
324
325 er_ret_t
326 RX_tree_cre (
327 char *prefixstr, /*+ prefix the tree will cover (string) +*/
328 rx_fam_t fam_id,
329 rx_mem_mt mem_mode, /* memory only, memory+sql, sql only +*/
330 rx_subtree_mt subtrees, /*+ one of NONE, AUTO, HAND +*/
331 rx_tree_t **treestore /* store the tree pointer here */
332 );
333
334 er_ret_t
335 RX_bin_search (
336 rx_srch_mt search_mode,
337 int par_a,
338 int par_b,
339 rx_tree_t *tree, /* tree ptr */
340 ip_prefix_t *prefix, /* binary prefix */
341 GList **datleaves, /* data leaves go here */
342 int max_count
343 );
344 er_ret_t
345 rx_bin_node (
346 rx_oper_mt mode, /*+ MODE={cre|mod|del} +*/
347 ip_prefix_t *newpref, /*+ prefix of the node +*/
348 rx_tree_t *tree, /*+ pointer to the tree structure +*/
349 rx_dataleaf_t *dataleaf /*+ dataleaf to attach at the node +*/
350 );
351 er_ret_t
352 RX_rt_node (
353 rx_oper_mt mode, /*+ MODE={cre|mod|del} +*/
354 ip_prefix_t *newpref, /*+ prefix of the node +*/
355 rx_tree_t *tree, /*+ pointer to the tree structure +*/
356 rx_dataleaf_t *dataleaf /*+ dataleaf to attach at the node +*/
357 );
358 er_ret_t
359 RX_in_node( rx_oper_mt mode, /*+ MODE={cre|mod|del} +*/
360 ip_range_t *rang, /*+ range of IP addresses +*/
361 rx_tree_t *tree, /*+ pointer to the tree structure +*/
362 rx_dataleaf_t *leafptr /*+ dataleaf to attach at the node +*/
363 );
364 er_ret_t
365 rx_build_stack(rx_nodcpy_t stack[],
366 int *maxdepth,
367 rx_tree_t *tree,
368 ip_prefix_t *newpref,
369 rx_stk_mt dmode
370 );
371
372 er_ret_t
373 rx_nod_search (
374 rx_srch_mt search_mode,
375 int par_a,
376 int par_b,
377 /* see rx_asc_search() for explanation */
378 rx_tree_t *tree, /* tree ptr */
379 ip_prefix_t *prefix, /* binary prefix */
380
381 rx_nodcpy_t stack[], /* stack==array of node_copies */
382 int stackcount, /* number of element on the stack*/
383 /* can be set in creat stack */
384
385 GList **nodlist, /* answers go here */
386 int max_count /* max # of answers */
387 );
388 int
389 rx_walk_tree(rx_node_t *node,
390 er_ret_t (*func)(rx_node_t *node, int level, int nodecounter,
391 void *userptr),
392 rx_walk_mt walk_mode,
393 int maxlevel,
394 int level,
395 int nodecounter,
396 void *userptr,
397 er_ret_t *err);
398
399
400 er_ret_t rx_tree_print( sk_conn_st *condat,rx_tree_t *tree );
401 void rx_space_list(sk_conn_st *condat);
402 void rx_nod_print( rx_node_t *node, char *buf, unsigned maxchar );
403 void rx_stk_print( rx_nodcpy_t stack[], int stackdepth );
404 const char *RX_text_srch_mode(rx_srch_mt mode);
405
406
407 /* Function needed to delete radix tree */
408 void
409 rx_delete_treenode(rx_tree_t *tree, rx_node_t *curnode);
410
411 int
412 rx_delete_tree(rx_tree_t *tree, rx_node_t *node,
413 int maxlevel,
414 int level,
415 int nodecounter,
416 void *userptr);
417
418
419 #undef EXTDEF
420 #endif /* _RX_H */