tree.c File Reference

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "defines.h"
#include "tree.h"
#include "util.h"

Functions

tnodetree_add (const char *key, const char *value, bool override, tnode **root)
 Adds specified key/value pair to tree as a node.
tnodetree_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.

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
1/4/2003

Function Documentation

tnode* tree_add ( const char *  key,
const char *  value,
bool  override,
tnode **  root 
)

Adds specified key/value pair to tree as a node.

Returns:
Returns pointer to newly created tree node.

Creates new node for this pairing and adds it to the binary tree for quick lookup.

Parameters:
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.

Parameters:
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 }

tnode* tree_find ( const char *  key,
tnode root 
)

Returns pointer to tree node that matches specified key.

Returns:
Returns pointer to found node or NULL if not found.

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.

Parameters:
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.

Parameters:
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 }

Generated on Sun Nov 21 00:55:41 2010 for Covered by  doxygen 1.6.3