00001
00017
00018
00019
00020
00021
00022
00023
00024 #include <sent/stddefs.h>
00025 #include <sent/ptree.h>
00026
00033 static APATNODE *
00034 new_node()
00035 {
00036 APATNODE *tmp;
00037
00038 tmp = (APATNODE *)mymalloc(sizeof(APATNODE));
00039 tmp->left0 = NULL;
00040 tmp->right1 = NULL;
00041
00042 return(tmp);
00043 }
00044
00045
00046 static char *tmp_str;
00047 static int maxbitplace;
00048
00056 static int
00057 testbit_local(int bitplace)
00058 {
00059 int maskptr;
00060 int bitshift;
00061 unsigned char maskbit;
00062
00063 if (bitplace >= maxbitplace) return 0;
00064 maskptr = bitplace / 8;
00065 if ((bitshift = bitplace % 8) != 0) {
00066 maskbit = 0x80 >> bitshift;
00067 } else {
00068 maskbit = 0x80;
00069 }
00070 return(tmp_str[maskptr] & maskbit);
00071 }
00072
00080 static void *
00081 aptree_search_data_r(APATNODE *node)
00082 {
00083 if (node->left0 == NULL && node->right1 == NULL) {
00084 return(node->value.data);
00085 } else {
00086 if (testbit_local(node->value.thres_bit) != 0) {
00087 return(aptree_search_data_r(node->right1));
00088 } else {
00089 return(aptree_search_data_r(node->left0));
00090 }
00091 }
00092 }
00093
00102 void *
00103 aptree_search_data(char *str, APATNODE *node)
00104 {
00105 if (node == NULL) {
00106 j_error("Error: aptree_search_data: no node, search for \"%s\" failed\n", str);
00107 }
00108 tmp_str = str;
00109 maxbitplace = strlen(str) * 8 + 8;
00110 return(aptree_search_data_r(node));
00111 }
00112
00113
00114
00115
00116
00124 APATNODE *
00125 aptree_make_root_node(void *data)
00126 {
00127 APATNODE *nnew;
00128
00129 nnew = new_node();
00130 nnew->value.data = data;
00131 return(nnew);
00132 }
00133
00142 static void
00143 aptree_add_entry_at(char *str, int bitloc, void *data, APATNODE **parentlink)
00144 {
00145 APATNODE *node;
00146 node = *parentlink;
00147 if (node->value.thres_bit > bitloc ||
00148 (node->left0 == NULL && node->right1 == NULL)) {
00149 APATNODE *newleaf, *newbranch;
00150
00151 newleaf = new_node();
00152 newleaf->value.data = data;
00153 newbranch = new_node();
00154 newbranch->value.thres_bit = bitloc;
00155 *parentlink = newbranch;
00156 if (testbit(str, bitloc) ==0) {
00157 newbranch->left0 = newleaf;
00158 newbranch->right1 = node;
00159 } else {
00160 newbranch->left0 = node;
00161 newbranch->right1 = newleaf;
00162 }
00163 return;
00164 } else {
00165 if (testbit(str, node->value.thres_bit) != 0) {
00166 aptree_add_entry_at(str, bitloc, data, &(node->right1));
00167 } else {
00168 aptree_add_entry_at(str, bitloc, data, &(node->left0));
00169 }
00170 }
00171 }
00172
00182 void
00183 aptree_add_entry(char *str, void *data, char *matchstr, APATNODE **rootnode)
00184 {
00185 int bitloc;
00186
00187 bitloc = where_the_bit_differ(str, matchstr);
00188 if (*rootnode == NULL) {
00189 *rootnode = aptree_make_root_node(data);
00190 } else {
00191 aptree_add_entry_at(str, bitloc, data, rootnode);
00192 }
00193
00194 }
00195
00196
00197
00198 static APATNODE *tmproot;
00199
00207 static void
00208 aptree_remove_entry_r(APATNODE *now, APATNODE *up, APATNODE *up2)
00209 {
00210 APATNODE *b;
00211
00212 if (now->left0 == NULL && now->right1 == NULL) {
00213
00214
00215
00216 if (up == NULL) {
00217 free(now);
00218 tmproot = NULL;
00219 return;
00220 }
00221 b = (up->right1 == now) ? up->left0 : up->right1;
00222 if (up2 == NULL) {
00223 free(now);
00224 free(up);
00225 tmproot = b;
00226 return;
00227 }
00228 if (up2->left0 == up) {
00229 up2->left0 = b;
00230 } else {
00231 up2->right1 = b;
00232 }
00233 free(now);
00234 free(up);
00235 return;
00236 } else {
00237
00238 if (testbit_local(now->value.thres_bit) != 0) {
00239 aptree_remove_entry_r(now->right1, now, up);
00240 } else {
00241 aptree_remove_entry_r(now->left0, now, up);
00242 }
00243 }
00244 }
00245
00253 void
00254 aptree_remove_entry(char *str, APATNODE **rootnode)
00255 {
00256 if (*rootnode == NULL) {
00257 j_error("Error: aptree_remove_entry: no node, deletion for \"%s\" failed\n", str);
00258 }
00259 tmproot = *rootnode;
00260 tmp_str = str;
00261 maxbitplace = strlen(str) * 8 + 8;
00262 aptree_remove_entry_r(tmproot, NULL, NULL);
00263 *rootnode = tmproot;
00264 }
00265
00266
00267
00275 void
00276 aptree_traverse_and_do(APATNODE *node, void (*callback)(void *))
00277 {
00278 if (node->left0 == NULL && node->right1 == NULL) {
00279 (*callback)(node->value.data);
00280 } else {
00281 if (node->left0 != NULL) {
00282 aptree_traverse_and_do(node->left0, callback);
00283 }
00284 if (node->right1 != NULL) {
00285 aptree_traverse_and_do(node->right1, callback);
00286 }
00287 }
00288 }
00289
00295 void
00296 free_aptree(APATNODE *node)
00297 {
00298 if (node->left0 != NULL) free_aptree(node->left0);
00299 if (node->right1 != NULL) free_aptree(node->right1);
00300 free(node);
00301 }