File modules/rx/rx_search.c

  $Revision: 1.20 $

Radix tree (rx). rx_search.c - functions to search nodes of the tree
Status: NOT REVUED, TESTED, INCOMPLETE
Design and implementation by: Marek Bukowy

Included Files


Global Function RX_asc_search()

  translates a query into a binary prefix (or prefixes, if range).
  for registry+space (or if they are zero, for all
  registries/spaces)
  finds tree 
  calls RX_bin_search (returning node copies).
  will not put duplicate entries (composed inetnums).
  returns some sort of error code :-) 

Cuts the number of answers from RX_bin_search down to max_count, but since some of the answers may have been "normalized" in the underlying functions (multiple occurences removed), the result is _at_most_ max_count.
appends to a given list of data blocks (not nodes!)
returns RX_OK or a code from an underlying function
er_ret_t RX_asc_search ( rx_srch_mt search_mode, int par_a, int par_b, char* key, int reg_id, ip_space_t spc_id, rx_fam_t fam_id, GList** anslist, int max_count )
rx_srch_mt search_mode
 
int par_a
MODE={exact|exless|less-depth|more-depth|more-bit} exless == our default search (exact or less-1 spec.) more-bit == more specific bit length searches: inclusive, exclusive, bit length, range of bit lengths... All of them can be expressed using a range of lengths. That means TWO integer parameters must be also given.
int par_b
 
char* key
search term: (string) prefix/range/IP
int reg_id
 
ip_space_t spc_id
space id, one of IPv4 IPv6.
rx_fam_t fam_id
RX_FAM_RT or RX_FAM_IN
GList** anslist
answers go here, please
int max_count
max # of answers. RX_ALLANS == unlimited
Prototyped in: include/rxroutines.h
Calls: ER_dbg_va()modules/er/er.c
  IP_pref_2_rang()modules/ip/ip.c
  IP_rang_decomp()modules/ip/ip.c
  IP_rang_span()modules/ip/ip.c
  IP_rang_t2b()modules/ip/ip.c
  IP_smart_conv()modules/ip/ip.c
  RX_bin_search()modules/rx/rx_search.c
  rx_preflist_search()modules/rx/rx_search.c
  RX_get_tree(), g_list_first(), g_list_foreach(), g_list_free(), g_list_length(), g_list_prepend(), g_list_remove(), memcmp(), memcpy(), wr_calloc(), wr_free()
Called by: QI_execute()modules/qi/query_instructions.c
References Functions: rx_free_list_element()modules/rx/rx_node.c

Global Function RX_bin_search()

  builds a stack for this prefix, finds *nodes* in the stack 
  and appends *copies of the data leaves* to the LL of answers;

sorts by SQL object keys and uniq's the data
finds: 0 or 1 nodes for exact search 0 or 1 nodes for exless (0 if no less specific node found) any number (incl. 0) for {more|less}-n specific
then copies the nodes/dataleaves to the answer structs and appends them to the given LL. So, effectively, the number of answers can be anything from 0 to infinity, because objects may be duplicate even at the same node.
returns errcode.
algorithm:
builds stack[MAXBIT (==128)];
if( more/less-depth && par_a == 0)
run rx_nod_search, then
if(more spec) rx_nod_walk(maxdepth=n, append_to_LL() ); if(less spec) do { append(LL, stack[i]) } while(i-- && n--); otherwise just set LL

The routine provides _at_least_ max_count answers. It will *try* to stop after max_count as soon as possible - but it's the higher level routine that should do the final cut.
er_ret_t RX_bin_search ( rx_srch_mt search_mode, int par_a, int par_b, rx_tree_t* tree, ip_prefix_t* prefix, GList** datleaves, int max_count )
Prototyped in: include/rxroutines.h
Calls: ER_dbg_va()modules/er/er.c
  rx_build_stack()modules/rx/rx_search.c
  rx_nod_search()modules/rx/rx_search.c
  fprintf(), g_list_first(), g_list_foreach(), g_list_free(), g_list_length(), g_list_nth_data(), g_list_prepend(), wr_calloc()
Called by: AC_check_acl()modules/ac/access_control.c
  AC_commit()modules/ac/access_control.c
  AC_fetch_acc()modules/ac/access_control.c
  RX_asc_search()modules/rx/rx_search.c
  rx_preflist_search()modules/rx/rx_search.c
References Functions: rx_free_list_element()modules/rx/rx_node.c

Global Function rx_build_stack()

Descends the given tree following the last prefix bit to get [past]
the node with the given prefix.
It fills up a stack of COPIES of nodes, including glue nodes.

Then it also sets the number of elements on the stack: set maxdepth to the position where a next one would be written ( = last + 1, or number of nodes pushed)
The dmodes:
RX_STK_QUERY_NOGLUE = (search exact/less spec) stop when * the current prefix length >= newprefix length * the current prefix does not match anymore * do not add glue nodes
RX_STK_QUERY_ALLNOD = as above, except that the glue and data nodes are treated equally (i.e. glue nodes are not skipped)
RX_STK_CREAT = descend until the next non-glue node past the one found in exact mode (for creation)
er_ret_t rx_build_stack ( rx_nodcpy_t stack[], int* maxdepth, rx_tree_t* tree, ip_prefix_t* newpref, rx_stk_mt dmode )
Prototyped in: include/rxroutines.h
Calls: ER_dbg_va()modules/er/er.c
  ER_is_traced()modules/er/er.c
  IP_addr_bit_get()modules/ip/ip.c
  IP_addr_cmp()modules/ip/ip.c
  IP_pref_b2a()modules/ip/ip.c
  memcpy()
Called by: RX_bin_node()modules/rx/rx_node.c
  RX_bin_search()modules/rx/rx_search.c

Global Function rx_nod_search()

er_ret_t rx_nod_search ( rx_srch_mt search_mode, int par_a, int par_b, rx_tree_t* tree, ip_prefix_t* prefix, rx_nodcpy_t stack[], int stackcount, GList** nodlist, int max_count, void )
Prototyped in: include/rxroutines.h
Calls: ER_dbg_va()modules/er/er.c
  ER_is_traced()modules/er/er.c
  IP_addr_cmp()modules/ip/ip.c
  IP_pref_b2a()modules/ip/ip.c
  rx_nod_append()modules/rx/rx_search.c
  rx_nod_print()modules/rx/rx_print.c
  fprintf(), memcmp(), rx_walk_tree()
Called by: RX_bin_node()modules/rx/rx_node.c
  RX_bin_search()modules/rx/rx_search.c
References Functions: rx_walk_hook_adddoubles()modules/rx/rx_search.c
  rx_walk_hook_addnode()modules/rx/rx_search.c

Local Function rx_find_leaf()

   this is a specialised find function to find nodes in the list of 
   answer structs that point to the given data leaf.
   This is used to avoid reporting data leaves more than once
   (eg. because the node is composed (inetnum) 
static GList* rx_find_leaf ( GList* anslist, rx_dataleaf_t* leafptr )
Calls: g_list_first()

Local Function rx_nod_append()

   helper for the nod_search routine: 

allocates a new node copy struct, copy the struct and add to nodlist
static er_ret_t rx_nod_append ( GList** nodlist, rx_nodcpy_t* element )
Calls: g_list_prepend(), memcpy(), wr_calloc()
Called by: rx_nod_search()modules/rx/rx_search.c
  rx_walk_hook_adddoubles()modules/rx/rx_search.c
  rx_walk_hook_addnode()modules/rx/rx_search.c

Local Function rx_preflist_search()

    this routine goes through the list of prefixes and performs a bin_search
   on each of them; attaches the results to datlist.
   Then, frees the prefix list.
static er_ret_t rx_preflist_search ( rx_srch_mt search_mode, int par_a, int par_b, rx_tree_t* mytree, GList** preflist, GList** datlist )
Calls: ER_dbg_va()modules/er/er.c
  IP_pref_b2a()modules/ip/ip.c
  RX_bin_search()modules/rx/rx_search.c
  fprintf(), g_list_first(), g_list_foreach(), g_list_free()
Called by: RX_asc_search()modules/rx/rx_search.c
References Functions: rx_free_list_element()modules/rx/rx_node.c

Local Function rx_walk_hook_adddoubles()

  helper for DBLS lookup in rx_nod_search 

adds a node to the list of answers.
static er_ret_t rx_walk_hook_adddoubles ( rx_node_t* node, int level, int nodecounter, void* userptr )
Calls: ER_dbg_va()modules/er/er.c
  ER_is_traced()modules/er/er.c
  rx_nod_append()modules/rx/rx_search.c
  rx_nod_print()modules/rx/rx_print.c
  g_list_length()
Used in: rx_nod_search()modules/rx/rx_search.c

Local Function rx_walk_hook_addnode()

  helper for MORE specific lookup in rx_nod_search 

adds a node to the list of answers.
static er_ret_t rx_walk_hook_addnode ( rx_node_t* node, int level, int nodecounter, void* userptr )
Calls: rx_nod_append()modules/rx/rx_search.c
  memset()
Used in: rx_nod_search()modules/rx/rx_search.c