#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "defines.h"
#include "tree.h"
#include "util.h"
Functions | |
tnode * | tree_add (const char *key, const char *value, bool override, tnode **root) |
Adds specified key/value pair to tree as a node. | |
tnode * | tree_find (const char *key, tnode *root) |
Returns pointer to tree node that matches specified key. | |
void | tree_remove (const char *key, tnode **root) |
Removes specified tree node from tree. | |
void | tree_dealloc (tnode *root) |
Deallocates entire tree from memory. |
Adds specified key/value pair to tree as a node.
Creates new node for this pairing and adds it to the binary tree for quick lookup.
key | String containing search key for node retrieval | |
value | Value associated with this node | |
override | If TRUE, causes new value to overwrite old value if match found | |
root | Pointer to root of tree to add to |
References FALSE, free_safe, tnode_s::left, malloc_safe, tnode_s::name, PROFILE, PROFILE_END, tnode_s::right, strdup_safe, TRUE, tnode_s::up, and tnode_s::value.
Referenced by obfuscate_name().
00049 { PROFILE(TREE_ADD); 00050 00051 tnode* node; /* Pointer to newly created tree node */ 00052 tnode* curr = *root; /* Pointer to current node */ 00053 bool placed = FALSE; /* Sets to TRUE when node is placed in tree */ 00054 int comp; /* Specifies compare value for string comparison */ 00055 00056 /* Allocate memory for tree node and populate */ 00057 node = (tnode*)malloc_safe( sizeof( tnode ) ); 00058 node->name = strdup_safe( key ); 00059 node->value = strdup_safe( value ); 00060 node->left = NULL; 00061 node->right = NULL; 00062 node->up = NULL; 00063 00064 /* Add node to tree */ 00065 if( *root == NULL ) { 00066 *root = node; 00067 } else { 00068 while( !placed ) { 00069 comp = strcmp( node->name, curr->name ); 00070 if( comp == 0 ) { 00071 00072 /* Match found, replace value with new value */ 00073 if( override ) { 00074 free_safe( curr->value, (strlen( curr->value ) + 1) ); 00075 curr->value = node->value; 00076 } else { 00077 free_safe( node->value, (strlen( node->value ) + 1) ); 00078 node->value = NULL; 00079 } 00080 00081 free_safe( node->name, (strlen( node->name ) + 1) ); 00082 free_safe( node, sizeof( tnode ) ); 00083 node = curr; 00084 placed = TRUE; 00085 00086 } else if( comp < 0 ) { 00087 00088 if( curr->left == NULL ) { 00089 curr->left = node; 00090 node->up = curr; 00091 placed = TRUE; 00092 } else { 00093 curr = curr->left; 00094 } 00095 00096 } else { 00097 00098 if( curr->right == NULL ) { 00099 curr->right = node; 00100 node->up = curr; 00101 placed = TRUE; 00102 } else { 00103 curr = curr->right; 00104 } 00105 00106 } 00107 } 00108 } 00109 00110 PROFILE_END; 00111 00112 return( node ); 00113 00114 }
void tree_dealloc | ( | tnode * | root | ) |
Deallocates entire tree from memory.
Recursively traverses specified tree, deallocating all memory associated with that tree.
root | Pointer to root of tree to deallocate |
References free_safe, tnode_s::left, tnode_s::name, PROFILE, PROFILE_END, tnode_s::right, tree_dealloc(), and tnode_s::value.
Referenced by db_close(), obfuscate_dealloc(), and tree_dealloc().
00275 { PROFILE(TREE_DEALLOC); 00276 00277 if( root != NULL ) { 00278 00279 if( root->left != NULL ) { 00280 tree_dealloc( root->left ); 00281 } 00282 00283 if( root->right != NULL ) { 00284 tree_dealloc( root->right ); 00285 } 00286 00287 free_safe( root->name, (strlen( root->name ) + 1) ); 00288 free_safe( root->value, (strlen( root->value ) + 1) ); 00289 free_safe( root, sizeof( tnode ) ); 00290 00291 } 00292 00293 PROFILE_END; 00294 00295 }
Returns pointer to tree node that matches specified key.
Searches binary tree for key that matches the specified name parameter. If found, a pointer to the node is returned; otherwise, the value of NULL is returned.
key | Key value to search for in tree | |
root | Pointer to root of binary tree to search |
References tnode_s::left, tnode_s::name, PROFILE, PROFILE_END, and tnode_s::right.
Referenced by obfuscate_name(), and tree_remove().
00126 { PROFILE(TREE_FIND); 00127 00128 int comp; /* Value of string comparison */ 00129 00130 while( (root != NULL) && ((comp = strcmp( key, root->name )) != 0) ) { 00131 if( comp < 0 ) { 00132 root = root->left; 00133 } else { 00134 root = root->right; 00135 } 00136 } 00137 00138 PROFILE_END; 00139 00140 return( root ); 00141 00142 }
void tree_remove | ( | const char * | key, | |
tnode ** | root | |||
) |
Removes specified tree node from tree.
Looks up the specified node (based on key value) and removes it from the tree in such a was as to keep the integrity of the tree in check for continual quick searching.
key | Key to search for and remove from tree | |
root | Pointer to root of tree to search |
References free_safe, tnode_s::left, tnode_s::name, PROFILE, PROFILE_END, tnode_s::right, tree_find(), tnode_s::up, and tnode_s::value.
00152 { PROFILE(TREE_REMOVE); 00153 00154 tnode* node; /* Pointer to found tree node to remove */ 00155 tnode* tail; /* Temporary pointer to tail node */ 00156 00157 /* Find undefined identifer string in table */ 00158 node = tree_find( key, *root ); 00159 00160 /* If node is found, restitch the define tree. */ 00161 if( node != NULL ) { 00162 00163 /* If we are the root node in the tree */ 00164 if( node->up == NULL ) { 00165 00166 /* If we have no children */ 00167 if( (node->left == NULL) && (node->right == NULL) ) { 00168 00169 *root = NULL; 00170 00171 } else if( node->left == NULL ) { 00172 00173 *root = node->right; 00174 if( node->right ) { 00175 node->right->up = NULL; 00176 } 00177 00178 } else if( node->right == NULL ) { 00179 00180 assert( node->left != NULL ); 00181 *root = node->left; 00182 (*root)->up = NULL; 00183 00184 } else { 00185 00186 tail = node->left; 00187 while( tail->right ) { 00188 tail = tail->right; 00189 } 00190 00191 tail->right = node->right; 00192 tail->right->up = tail; 00193 *root = node->left; 00194 (*root)->up = NULL; 00195 00196 } 00197 00198 } else if( node->left == NULL ) { 00199 00200 if( node->up->left == node ) { 00201 00202 node->up->left = node->right; 00203 00204 } else { 00205 00206 assert( node->up->right == node ); 00207 node->up->right = node->right; 00208 00209 } 00210 00211 if( node->right ) { 00212 node->right->up = node->up; 00213 } 00214 00215 } else if( node->right == NULL ) { 00216 00217 assert( node->left != NULL ); 00218 00219 if( node->up->left == node ) { 00220 00221 node->up->left = node->left; 00222 00223 } else { 00224 00225 assert( node->up->right == node ); 00226 node->up->right = node->left; 00227 00228 } 00229 00230 node->left->up = node->up; 00231 00232 } else { 00233 00234 tail = node->left; 00235 assert( (node->left != NULL) && (node->right != NULL) ); 00236 00237 while( tail->right ) { 00238 tail = tail->right; 00239 } 00240 00241 tail->right = node->right; 00242 tail->right->up = tail; 00243 00244 if( node->up->left == node ) { 00245 00246 node->up->left = node->left; 00247 00248 } else { 00249 00250 assert( node->up->right == node ); 00251 node->up->right = node->left; 00252 00253 } 00254 00255 node->left->up = node->up; 00256 00257 } 00258 00259 free_safe( node->name, (strlen( node->name ) + 1) ); 00260 free_safe( node->value, (strlen( node->value ) + 1) ); 00261 free_safe( node, sizeof( tnode ) ); 00262 00263 } 00264 00265 PROFILE_END; 00266 00267 }