## 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.7 $
       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                              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 <rp.h>
      35 #include <rxroutines.h>
      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     dieif(wr_malloc((void **) &treedef, sizeof(rp_tentry_t)) != UT_OK);
     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 %08x: %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   /* Some (DN) attributes are related to two trees */
     171   if( RP_attr2spc(attr, IP_V4) ) {
     172     err=RP_tree_add(reg_id, attr, "0.0.0.0/0",
     173                     RX_MEM_RAMONLY, RX_SUB_NONE);
     174   }
     175
     176   if( RP_attr2spc(attr, IP_V6) ) {
     177    err=RP_tree_add(reg_id, attr, "0::/0",
     178                    RX_MEM_RAMONLY, RX_SUB_NONE);
     179   }
     180
     181   return err;
     182 }
     183 /***************************************************************************/
     184
     185 er_ret_t
     186 RP_init_trees( rp_regid_t reg_id )
         /* [<][>][^][v][top][bottom][index][help] */
     187 {
     188   er_ret_t err;
     189
     190   if(    NOERR(err=rp_init_attr_tree(reg_id, A_IN))
     191       && NOERR(err=rp_init_attr_tree(reg_id, A_RT))
     192       && NOERR(err=rp_init_attr_tree(reg_id, A_I6))
     193       && NOERR(err=rp_init_attr_tree(reg_id, A_DN)) ) {
     194     return RP_OK;
     195   }
     196
     197   return err;
     198 }
     199
     200
     201
     202

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