#include"heap.h" #include #include #include #define LIBRARYIMPLEMENTATION typedef struct{ heap *lib_on_which_heap; struct libnode *root; long number_of_entries; }library; struct libnode{ struct libnode *left; struct libnode *right; long how_often_occurred; unsigned char *string; }; #include "library.h" static void fill_nodelist( struct libnode *node, struct libnode ***nodelist ); static int compare( struct libnode **first, struct libnode **second ); static void fill_tree_hist(struct libnode *node,long tree_hist[],long weight_hist[],long histlenght,long *deepest_branch,int depth); static struct libnode *reorder(struct libnode *node, long *depth,long level); library *library_create( long blocksize ) { library *lib; heap *lib_heap; if( NULL == ( lib_heap = heap_create( blocksize ))) return(NULL); if( NULL == ( lib = heap_allocate( lib_heap, sizeof( library )))) return(NULL); lib->lib_on_which_heap = lib_heap; lib->root = NULL; lib->number_of_entries = 0; return(lib); } /* library_create */ void library_delete( library *lib ) { heap_delete( lib->lib_on_which_heap ); } int library_read( library *lib, FILE *libfile ) /* reads library */ { long occurrences; unsigned char string[256]; while(!feof(libfile)) { if (!fscanf(libfile,"%s\t%ld\n", string, &occurrences)) break; if ( occurrences <= 0 ) break; if (!library_enter_entry( lib, string, occurrences )) return(0); /* eintragen hat nicht geklappt */ } /* while !feof() */ return(1); } int library_write( library *lib, FILE *libfile ) { long i; struct libnode **localptr; struct libnode **nodelist; if ( NULL == (nodelist = (struct libnode **)malloc( sizeof(struct libnode *)*lib->number_of_entries))) return(0); localptr = nodelist; fill_nodelist( lib->root, &localptr ); qsort( nodelist, lib->number_of_entries, sizeof( struct libnode *), (int (*)(const void *, const void *)) compare ); /* the qsort is buggy in some libraries, to have a look at the result!! */ for(i = 0; i < lib->number_of_entries; i++ ) fprintf( libfile, "%s\t%ld\n", nodelist[i]->string, nodelist[i]->how_often_occurred); fprintf( libfile, "end-of-file\t-1\n"); free(nodelist); return(1); } /* library_write */ static void fill_nodelist( struct libnode *node, struct libnode ***nodelist ) { if( node ) { *((*nodelist)++) = node; fill_nodelist( node->left, nodelist ); fill_nodelist( node->right, nodelist ); } } /* fill_nodelist */ static int compare( struct libnode **first, struct libnode **second ) { long local; local =(*first)->how_often_occurred - (*second)->how_often_occurred; if (local < 0 ) return( 1 ); if (local > 0 ) return( -1 ); return( 0 ); } int library_enter_entry( library *lib, const unsigned char *string, long occurrences_so_far ) { int comp = 1; struct libnode *node; struct libnode **dest; if( lib->root == NULL ) /* leere lib */ dest = &(lib->root); else { node = lib->root; while( 0 != ( comp = strcmp(node->string,string))) { if ( comp > 0 ) { if ( node->left ) { node = node->left; continue; } else { dest = &(node->left); break; } } else if( comp < 0 ) { if ( node->right ) { node = node->right; continue; } else { dest = &(node->right); break; } } } } if ( comp == 0 ) { node->how_often_occurred += occurrences_so_far; return( 1 ); } *dest = heap_allocate( lib->lib_on_which_heap, sizeof(struct libnode)+ strlen(string)+1 ); if(!*dest ) return( 0 ); (*dest)->left = NULL; (*dest)->right = NULL; (*dest)->string = (unsigned char *)( *dest + 1 ); /* da soll der string hin (hinter libnode) */ (*dest)->how_often_occurred = occurrences_so_far; strcpy((*dest)->string, string ); lib->number_of_entries++; return( 1 ); } /* library_enter_entry */ int library_find_entry( library *lib, const unsigned char *string ) { struct libnode *node; int comp; if ( lib->root == NULL ) return( 0 ); node = lib->root; while( 0 != ( comp = strcmp(node->string,string))) { if (( comp > 0 )&&(node->left)) { node = node->left; continue; } else if(( comp < 0 )&&( node->right )) { node = node->right; continue; } return( 0 ); } return( 1 ); } /* find_entry liefert pointer auf libnode */ void library_fill_hist(library *lib,long tree_hist[],long weight_hist[],long histlenght,long *deepest_branch) { fill_tree_hist( lib->root,tree_hist,weight_hist,histlenght,deepest_branch,0); } static void fill_tree_hist(struct libnode *node,long tree_hist[],long weight_hist[],long histlenght,long *deepest_branch,int depth) { if (node) { fill_tree_hist(node->left,tree_hist,weight_hist,histlenght,deepest_branch,depth+1); if (depth < histlenght) { tree_hist[depth]++; weight_hist[depth] += node->how_often_occurred; } else tree_hist[histlenght]++; if (depth > *deepest_branch) *deepest_branch = depth; fill_tree_hist(node->right,tree_hist,weight_hist,histlenght,deepest_branch,depth+1); } } int library_reorganize(library *lib) { long depth = 0; lib->root = reorder(lib->root,&depth,0); return((int)lib->root); } static struct libnode *reorder(struct libnode *node, long *depth, long level) { if (node) { long left_depth; long right_depth; long newdepth; struct libnode *help; help = node; newdepth = *depth; node->left = reorder(node->left, depth, level + 1); left_depth = *depth; *depth = newdepth; node->right = reorder(node->right, depth, level + 1); right_depth = *depth; *depth = right_depth > left_depth ? right_depth : left_depth; if (right_depth > left_depth) { /* rechts rotieren */ if (node->right) { if (node->right->how_often_occurred == node->how_often_occurred) { help = node->right; node->right = help->left; help->left = node; }; }; } /* links rotieren */ else if (left_depth > right_depth) { if (node->left) { if (node->left->how_often_occurred == node->how_often_occurred) { help = node->left; node->left = help->right; help->right = node; }; }; }; return(help); }; if (level > *depth) *depth = level; return(node); }