modules/rp/rp_tree.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. RP_tree_get
  2. RP_tree_add
  3. RP_tree_del
  4. rp_init_attr_tree
  5. RP_init_trees

   1 /***************************************
   2   $Revision: 1.9 $
   3 
   4   Radix payload (rp) - user level functions for storing data in radix trees
   5 
   6   rp_load = user level tree maintenance (knows about registries and attributes)
   7 
   8   Status: NOT REVIEWED, TESTED
   9   
  10   Design and implementation by: Marek Bukowy
  11   
  12   ******************/ /******************
  13   Copyright (c) 1999,2000,2001,2002               RIPE NCC
  14  
  15   All Rights Reserved
  16   
  17   Permission to use, copy, modify, and distribute this software and its
  18   documentation for any purpose and without fee is hereby granted,
  19   provided that the above copyright notice appear in all copies and that
  20   both that copyright notice and this permission notice appear in
  21   supporting documentation, and that the name of the author not be
  22   used in advertising or publicity pertaining to distribution of the
  23   software without specific, written prior permission.
  24   
  25   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  26   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  27   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  28   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  29   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  30   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  31   ***************************************/
  32 
  33 #define RP_IMPL
  34 #include "rip.h"
  35 
  36 /***************************************************************************/
  37 /*++++++++++++++
  38   finds a tree matching the specified criteria(registry+space+family+tid).
  39 
  40   MT-note: locks/unlocks forest (still to be done)
  41 
  42   Returns: RX_OK or RX_NOTREE if no such tree can be found.
  43 +++++++++++*/
  44 
  45 er_ret_t 
  46 RP_tree_get ( rx_tree_t **treeptr, /*+ answer goes here, please +*/
     /* [<][>][^][v][top][bottom][index][help] */
  47               rp_regid_t reg_id,   /*+ id of the registry +*/
  48               ip_space_t spc_id,   /*+ type of space (ipv4/ipv6) +*/
  49               rp_attr_t  attr    /*+ extra tree id (within the same reg/spc/fam +*/
  50               )
  51      
  52 {
  53   GList *elem;
  54   rp_tentry_t  *trdef;
  55   /* lock the forest */
  56   TH_acquire_read_lockw(&rx_forest_rwlock);
  57   elem = g_list_first(rx_forest);
  58   
  59   while( elem != NULL ) {
  60     trdef = elem->data;
  61     
  62     
  63     if(    trdef->reg_id == reg_id   
  64         && trdef->attr == attr 
  65         && trdef->tree->space == spc_id ) {
  66       /* copy the value to user's data */
  67       *treeptr = trdef->tree;
  68       ER_dbg_va(FAC_RP, ASP_RP_TREE_DET, 
  69                 "tree found at %08x -> %08x",trdef, trdef->tree);
  70       return RP_OK;
  71     }
  72     elem = g_list_next(elem);
  73   }
  74   
  75   *treeptr = NULL; /* set when NOT FOUND*/
  76   TH_release_read_lockw(&rx_forest_rwlock);
  77 /*  pthread_mutex_unlock(&rx_forest_mx);*/
  78   return RP_NOTREE; 
  79 }
  80 
  81 
  82 
  83 /*++++++++++++++++++++++++++++++++
  84        put into LL of trees; handle alloc err ??? 
  85 
  86        since other threads are supposed to be reading already, 
  87        must create the tree locked and observe the forest mutex.
  88        ++++++++++++++++++++*/
  89 er_ret_t 
  90 RP_tree_add (
     /* [<][>][^][v][top][bottom][index][help] */
  91              rp_regid_t reg_id,    /*+ id of the registry +*/
  92              rp_attr_t  attr,      /*+ extra tree id (within the same registry/space/family +*/
  93              char      *prefixstr, /*+ prefix the tree will cover (string) +*/
  94              rx_mem_mt   mem_mode, /* memory only, memory+sql, sql only +*/
  95              rx_subtree_mt subtrees     /*+ one of NONE, AUTO, HAND +*/
  96              )
  97 {
  98   er_ret_t     err;
  99   rp_tentry_t *treedef;
 100   rx_tree_t   *mytree;
 101   rx_tree_t   *existree;
 102   rx_fam_t   fam_id = RP_attr2fam( attr );
 103 
 104   if( (err = RX_tree_cre(prefixstr, fam_id, mem_mode, subtrees, &mytree)) == RX_OK) {
 105 
 106     /* OK, see if there is a tree for this space already */
 107     if( RP_tree_get(&existree, reg_id, mytree->space, attr) == RP_OK ) {
 108       /* In this case we need to delete and re-initialize it  */
 109       /* lock the tree for writing and leave it in the locked state for loading */
 110       TH_acquire_write_lockw(&existree->rwlock);
 111 
 112       if( (err = RP_tree_del(existree)) == RP_OK){
 113               /* Initialize the tree */
 114               existree->num_nodes=0;
 115       }
 116       /* free the newly created tree */
 117       UT_free(mytree);
 118       return err;      
 119     }
 120 
 121     treedef = (rp_tentry_t *)UT_malloc(sizeof(rp_tentry_t));
 122     
 123     treedef -> reg_id = reg_id;
 124     treedef -> attr   = attr;
 125     treedef -> tree   = mytree;
 126 
 127     /* add the tree to the forest in locked state */
 128     TH_acquire_write_lockw( &(mytree->rwlock) );
 129     
 130     /* Lock the forest */
 131     TH_acquire_write_lockw(&rx_forest_rwlock);
 132     rx_forest = g_list_append (rx_forest, treedef);
 133     TH_release_write_lockw(&rx_forest_rwlock);
 134   }
 135   
 136   return err;
 137 }
 138 
 139 /*++++++++++++++
 140   finds a tree and deletes its contents
 141   the tree itself is not deleted !
 142 
 143   Returns: RX_OK or RX_NOTREE if no such tree can be found.
 144 +++++++++++*/
 145 
 146 er_ret_t 
 147 RP_tree_del ( rx_tree_t *tree )
     /* [<][>][^][v][top][bottom][index][help] */
 148 {
 149 int cnt;
 150 
 151   if( tree->top_ptr != NULL ) {
 152     cnt = rx_delete_tree(tree, tree->top_ptr, 255, 0, 0, NULL);
 153     ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN,
 154                "tree at %08x: %d nodes deleted", tree, cnt);    
 155          if (cnt != tree->num_nodes){
 156                  ER_perror(FAC_RP, RP_NOYETI,
 157                 "tree at %p: %d nodes deleted, should be %d", tree, cnt, tree->num_nodes);
 158                  return  RP_NOYETI;
 159          }
 160   }
 161   return RP_OK;
 162 }
 163 
 164 
 165 er_ret_t 
 166 rp_init_attr_tree( rp_regid_t reg_id, rp_attr_t attr)
     /* [<][>][^][v][top][bottom][index][help] */
 167 {
 168   er_ret_t err;
 169   
 170   err = RP_OK;
 171 
 172   /* Some (DN) attributes are related to two trees */
 173   if( RP_attr2spc(attr, IP_V4) ) {
 174     err=RP_tree_add(reg_id, attr, "0.0.0.0/0",
 175                     RX_MEM_RAMONLY, RX_SUB_NONE);
 176   } 
 177   
 178   if( RP_attr2spc(attr, IP_V6) ) {
 179    err=RP_tree_add(reg_id, attr, "0::/0",
 180                    RX_MEM_RAMONLY, RX_SUB_NONE);
 181   }
 182   
 183   return err;
 184 }
 185 /***************************************************************************/
 186 
 187 er_ret_t 
 188 RP_init_trees( rp_regid_t reg_id )
     /* [<][>][^][v][top][bottom][index][help] */
 189 {
 190   er_ret_t err;
 191   
 192   if(    NOERR(err=rp_init_attr_tree(reg_id, A_IN))
 193       && NOERR(err=rp_init_attr_tree(reg_id, A_RT))
 194       && NOERR(err=rp_init_attr_tree(reg_id, A_I6))
 195       && NOERR(err=rp_init_attr_tree(reg_id, A_DN)) ) {
 196     return RP_OK;
 197   }
 198   
 199   return err;
 200 }
 201 
 202 
 203 
 204 

/* [<][>][^][v][top][bottom][index][help] */