libsent/src/util/aptree.c

Go to the documentation of this file.
00001 
00017 /*
00018  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00019  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00020  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology
00021  * All rights reserved
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 /* temporary work area for search */
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 /* add 1 node to given ptree */
00116 
00124 APATNODE *
00125 aptree_make_root_node(void *data)
00126 {
00127   APATNODE *nnew;
00128   /* make new leaf node for newstr */
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     /* insert between [parent] and [node] */
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     /* assume this is exactly the node of data that has specified key string */
00214     /* make sure the data of your removal request already exists before call this */
00215     /* execute removal */
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     /* traverse */
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 == NULL) return;
00299   if (node->left0 != NULL) free_aptree(node->left0);
00300   if (node->right1 != NULL) free_aptree(node->right1);
00301   free(node);
00302 }

Generated on Tue Dec 26 16:16:33 2006 for Julius by  doxygen 1.5.0