/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- RP_uni_node_l
- RP_uni_node
- RP_asc_node
- RP_pack_node
- RP_pack_node_l
1 /***************************************
2 $Revision: 1.13 $
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,2000,2001,2002 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 "rip.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} +*/
/* [<][>][^][v][top][bottom][index][help] */
39 rp_uni_t *uni,
40 rx_tree_t *mytree,
41 void *data, /*+ pointer to the payload +*/
42 unsigned 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 leafptr = (rx_dataleaf_t *)UT_calloc(1, sizeof(rx_dataleaf_t));
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 leafptr->data_ptr = UT_malloc(datalen);
56 memcpy(leafptr->data_ptr, data, datalen);
57 leafptr->data_len = datalen;
58 }
59
60 switch( mytree->family ) {
61 case RX_FAM_IN:
62 err = RX_in_node( mode, &(uni->u.in), mytree, leafptr );
63 break;
64 case RX_FAM_RT:
65 err = RX_rt_node( mode, &(uni->u.rt), mytree, leafptr );
66 break;
67 default:
68 die;
69 err = RP_BADKEY;
70 }
71
72 if( mode != RX_OPER_CRE ) {
73 UT_free(leafptr);
74 }
75
76 return err;
77 }
78
79
80
81 /*+ ***************************************************************
82
83 MAIN FRONTEND FUNCTION
84
85
86 finds tree, locks it.
87
88 builds a dataleaf and puts into the node(s),
89 calling rx_bin_node for every prefix.
90
91 MT-note: locks/unlocks the tree.
92
93 +++++++++++++++++*/
94 er_ret_t
95 RP_uni_node ( rx_oper_mt mode, /*+ MODE={cre|mod|del} +*/
/* [<][>][^][v][top][bottom][index][help] */
96 rp_uni_t *uni, /*+ unified argument structure +*/
97 rp_attr_t attr, /*+ additional tree attribute +*/
98 rp_regid_t reg_id, /*+ id of the registry +*/
99 void *data, /*+ pointer to the payload +*/
100 unsigned datalen, /*+ length of the payload +*/
101 sql_key_t key /*+ the key to the SQL full-text +*/
102 )
103 {
104
105 /*
106 For creation of a new node:
107
108 READ-LOCK THE FOREST
109
110 get the root tree for this space (rx_get_tree)
111 got it ? good. No ? error!!!
112
113 Check if any of the prefixes spans more than one subtree...
114 Check if they all exist already..
115
116 abort if any is missing
117
118 UNLOCK THE FOREST
119
120 **now start writing the data:**
121
122 put *data* records in memory and sql table
123
124 for all matchind [sub]trees (in order of the list)
125 WRITE-LOCK the in-memory [sub]tree
126 WRITE-LOCK the sql-table for it
127
128 for(all prefixes in memory that match this tree)
129 create a node in the tree pointing to the data
130 rof
131 UNLOCK the tree
132 rof
133
134
135 */
136
137 rx_tree_t *mytree;
138 ip_space_t space = uni->space;
139 er_ret_t err;
140
141
142 dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
143
144 /* LOCK */
145 TH_acquire_write_lockw( &(mytree->rwlock) );
146
147 err = RP_uni_node_l (mode, uni, mytree, data, datalen, key);
148
149 /* UNLOCK */
150 TH_release_write_lockw( &(mytree->rwlock) );
151
152 return err;
153 }
154
155 /*+ *********************************************************************
156 Ascii frontend - translates key according to attr and calls rx_uni_node.
157 FOR TESTING PURPOSES ONLY
158 ********************************************************************* +*/
159 er_ret_t
160 RP_asc_node( rx_oper_mt mode, /*+ MODE={cre|mod|del} +*/
/* [<][>][^][v][top][bottom][index][help] */
161 char *rangstr, /*+ string prefix/range/IP/inaddr +*/
162 rp_attr_t attr, /*+ additional tree attribute +*/
163 rp_regid_t reg_id, /*+ id of the registry +*/
164 void *data, /*+ pointer to the payload +*/
165 unsigned datalen, /*+ length of the payload +*/
166 sql_key_t key /*+ the key to the SQL full-text +*/
167 )
168 {
169 rp_uni_t uni;
170
171 if( RP_asc2uni( rangstr, attr, &uni ) != IP_OK ) {
172 ER_dbg_va(FAC_RX, ASP_RX_NODCRE_DET,
173 "can't understand the key, discarding the OBJECT.");
174 return RP_BADKEY;
175 }
176 else {
177 ER_dbg_va(FAC_RX, ASP_RX_NODCRE_DET,
178 "rx_asc_node: inserting object %s for attr %d reg %d \twith %d bytes at %x",
179 rangstr, attr, reg_id, datalen, data);
180 return RP_uni_node(mode, &uni, attr, reg_id, data, datalen, key);
181 }
182 }
183
184 /***************************************************************************/
185
186 er_ret_t
187 RP_pack_node(rx_oper_mt mode,
/* [<][>][^][v][top][bottom][index][help] */
188 rp_upd_pack_t *pack,
189 rp_regid_t reg_id) /*+ id of the registry +*/
190 {
191 char *rx_text = "";
192 unsigned len=0;/* doesn't matter for deletion */
193 rp_uni_t *uniptr;
194
195 if(mode != RX_OPER_DEL) {
196 rp_make_short(pack, &rx_text, &len);
197 }
198
199 uniptr = &(pack->uni);
200 return RP_uni_node(mode, uniptr, pack->type, reg_id,
201 rx_text, len+1, pack->key);
202 }
203 /***************************************************************************/
204
205 er_ret_t
206 RP_pack_node_l(rx_oper_mt mode,
/* [<][>][^][v][top][bottom][index][help] */
207 rp_upd_pack_t *pack,
208 rx_tree_t *mytree)
209 {
210 char *rx_text = "";
211 unsigned len=0;/* doesn't matter for deletion */
212 rp_uni_t *uniptr;
213
214 if(mode != RX_OPER_DEL) {
215 rp_make_short(pack, &rx_text, &len);
216 }
217
218 uniptr = &(pack->uni);
219
220 return RP_uni_node_l(mode, uniptr, mytree,
221 rx_text, strlen(rx_text)+1, pack->key);
222 }