Source File modules/rp/rp_update.c

    1    | /***************************************
    2    |   $Revision: 1.5 $
    3    |
    4    |   Radix tree (rx).  rx_payload.c - functions to operate on user data
    5    |   (creation/deletion).
    6    |
    7    |   Status: NOT REVUED, UNTESTED, INCOMPLETE
    8    |
    9    |   Design and implementation by: Marek Bukowy
    10   |
    11   |   ******************/ /******************
    12   |   Copyright (c) 1999                              RIPE NCC
    13   |
    14   |   All Rights Reserved
    15   |
    16   |   Permission to use, copy, modify, and distribute this software and its
    17   |   documentation for any purpose and without fee is hereby granted,
    18   |   provided that the above copyright notice appear in all copies and that
    19   |   both that copyright notice and this permission notice appear in
    20   |   supporting documentation, and that the name of the author not be
    21   |   used in advertising or publicity pertaining to distribution of the
    22   |   software without specific, written prior permission.
    23   |
    24   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    25   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    26   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    27   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    28   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    29   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    30   |   ***************************************/
    31   |
    32   | #include <rp.h>
    33   |
    34   | /*+ ***************************************************************
    35   |   assumes locked tree
    36   |   +*/
    37   | er_ret_t
    38   | RP_uni_node_l ( rx_oper_mt mode,       /*+ MODE={cre|mod|del} +*/
    39   | 		rp_uni_t   *uni,
    40   | 		rx_tree_t  *mytree,
    41   | 		void *data,            /*+ pointer to the payload +*/
    42   | 		int   datalen,         /*+ length of the payload +*/
    43   | 		sql_key_t key          /*+ the key to the SQL full-text +*/
    44   | 		)
    45   | {
    46   |   rx_dataleaf_t *leafptr;
    47   |   er_ret_t err;
    48   |
    49   |   /* set the data leaf values*/
    50   |   dieif( wr_calloc( (void **)& leafptr, sizeof(rx_dataleaf_t), 1) != UT_OK );
    51   |   leafptr->data_key = key;  /* also for deletion - it is used for finding the
    52   | 			       right dataleaf in the tree */
    53   |
    54   |   if( mode == RX_OPER_CRE ) {
    55   |       dieif( wr_malloc( (void **)& (leafptr->data_ptr), datalen) != UT_OK );
    56   |
    57   |       memcpy(leafptr->data_ptr, data, datalen);
    58   |       leafptr->data_len = datalen;
    59   |   }
    60   |
    61   |   switch( mytree->family ) {
    62   |   case RX_FAM_IN:
    63   |     err = RX_in_node( mode, &(uni->u.in), mytree, leafptr );
    64   |     break;
    65   |   case RX_FAM_RT:
    66   |     err = RX_rt_node( mode, &(uni->u.rt), mytree, leafptr );
    67   |     break;
    68   |   default:
    69   |     die;
    70   |     err = RP_BADKEY;
    71   |   }
    72   |
    73   |   if( mode != RX_OPER_CRE ) {
    74   |       wr_free(leafptr);
    75   |   }
    76   |
    77   |   return err;
    78   | }
    79   |
    80   |
    81   |
    82   | /*+ ***************************************************************
    83   |
    84   |   MAIN FRONTEND FUNCTION
    85   |
    86   |
    87   |   finds tree, locks it.
    88   |
    89   |   builds a dataleaf and puts into the node(s),
    90   |   calling rx_bin_node for every prefix.
    91   |
    92   |   MT-note: locks/unlocks the tree.
    93   |
    94   | +++++++++++++++++*/
    95   | er_ret_t
    96   | RP_uni_node ( rx_oper_mt mode,       /*+ MODE={cre|mod|del} +*/
    97   | 	      rp_uni_t   *uni,       /*+ unified argument structure +*/
    98   | 	      rp_attr_t  attr,       /*+ additional tree attribute +*/
    99   | 	      rp_regid_t reg_id,     /*+ id of the registry +*/
    100  | 	      void *data,            /*+ pointer to the payload +*/
    101  | 	      int   datalen,         /*+ length of the payload +*/
    102  | 	      sql_key_t key          /*+ the key to the SQL full-text +*/
    103  | 	      )
    104  | {
    105  |
    106  |   /*
    107  |    For creation of a new node:
    108  |
    109  |      READ-LOCK THE FOREST
    110  |
    111  |      get the root tree for this space (rx_get_tree)
    112  |      got it ? good. No ? error!!!
    113  |
    114  |      Check if any of the prefixes spans more than one subtree...
    115  |      Check if they all exist already..
    116  |
    117  |      abort if any is missing
    118  |
    119  |      UNLOCK THE FOREST
    120  |
    121  |      **now start writing the data:**
    122  |
    123  |      put *data* records in memory and sql table
    124  |
    125  |      for all matchind [sub]trees (in order of the list)
    126  | 	 WRITE-LOCK the in-memory [sub]tree
    127  | 	 WRITE-LOCK the sql-table for it
    128  |
    129  | 	 for(all prefixes in memory that match this tree)
    130  | 	     create a node in the tree pointing to the data
    131  | 	 rof
    132  | 	 UNLOCK the tree
    133  |      rof
    134  |
    135  |
    136  | */
    137  |
    138  |   rx_tree_t     *mytree;
    139  |   ip_space_t    space = uni->space;
    140  |   er_ret_t      err;
    141  |
    142  |
    143  |   dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
    144  |
    145  |   /* XXX LOCK */
    146  |   TH_acquire_write_lock( &(mytree->rwlock) );
    147  |
    148  |   err = RP_uni_node_l (mode, uni, mytree, data, datalen, key);
    149  |
    150  |   /* XXX UNLOCK */
    151  |   TH_release_write_lock( &(mytree->rwlock) );
    152  |
    153  |   return err;
    154  | }
    155  |
    156  | /*+ *********************************************************************
    157  |   Ascii frontend - translates key according to attr and calls rx_uni_node.
    158  |   FOR TESTING PURPOSES ONLY
    159  |   ********************************************************************* +*/
    160  | er_ret_t
    161  | RP_asc_node( rx_oper_mt mode,       /*+ MODE={cre|mod|del} +*/
    162  | 	       char *rangstr,         /*+ string prefix/range/IP/inaddr +*/
    163  | 	       rp_attr_t  attr,       /*+ additional tree attribute +*/
    164  | 	       rp_regid_t reg_id,     /*+ id of the registry +*/
    165  | 	       void *data,            /*+ pointer to the payload +*/
    166  | 	       int   datalen,         /*+ length of the payload +*/
    167  | 	       sql_key_t key          /*+ the key to the SQL full-text +*/
    168  |               )
    169  | {
    170  |   rp_uni_t uni;
    171  |
    172  |   if( RP_asc2uni( rangstr, attr, &uni )  != IP_OK ) {
    173  |     ER_dbg_va(FAC_RX, ASP_RX_NODCRE_BOT,
    174  |               "can't understand the key, discarding the OBJECT.");
    175  |     return RP_BADKEY;
    176  |   }
    177  |   else {
    178  |     ER_dbg_va(FAC_RX, ASP_RX_NODCRE_BOT,
    179  |               "rx_asc_node: inserting object %s for attr %d reg %d \twith %d bytes at %x",
    180  | 	      rangstr, attr, reg_id, datalen, data);
    181  |     return RP_uni_node(mode, &uni, attr, reg_id, data, datalen, key);
    182  |   }
    183  | }
    184  |
    185  | /***************************************************************************/
    186  |
    187  | er_ret_t
    188  | RP_pack_node(rx_oper_mt   mode,
    189  | 	     rp_upd_pack_t *pack,
    190  | 	     rp_regid_t    reg_id)       /*+ id of the registry +*/
    191  | {
    192  |   char     *rx_text = "";
    193  |   int      len;
    194  |   rp_uni_t *uniptr;
    195  |
    196  |   if(mode != RX_OPER_DEL) {
    197  |     rp_make_short(pack, &rx_text, &len);
    198  |   }
    199  |
    200  |   uniptr = &(pack->uni);
    201  |
    202  |   return RP_uni_node(mode, uniptr, pack->type, reg_id, rx_text, len, pack->key);
    203  | }
    204  | /***************************************************************************/
    205  |
    206  | er_ret_t
    207  | RP_pack_node_l(rx_oper_mt    mode,
    208  | 	       rp_upd_pack_t *pack,
    209  | 	       rx_tree_t     *mytree)
    210  | {
    211  |   char     *rx_text = "";
    212  |   int      len;
    213  |   rp_uni_t *uniptr;
    214  |
    215  |   if(mode != RX_OPER_DEL) {
    216  |     rp_make_short(pack, &rx_text, &len);
    217  |   }
    218  |
    219  |   uniptr = &(pack->uni);
    220  |
    221  |   return RP_uni_node_l(mode, uniptr, mytree,
    222  | 		       rx_text, strlen(rx_text)+1, pack->key);
    223  | }