/** * Find a child of an internal node starting with a character * @param v the internal node * @param c the char to look for * @return the child node */ static node *find_child( node *v, char c ) { v = node_children(v); while ( v != NULL && str[node_start(v)] != c ) v = node_next(v); return v; }
/** * Set the length of each leaf to e recursively * @param v the node in question */ static void set_e( node *v ) { if ( node_is_leaf(v) ) { node_set_len( v, e-node_start(v)+1 ); } node *u = node_children( v ); while ( u != NULL ) { set_e( u ); u = node_next( u ); } }
long calc_similars(const char* line) { root = build_tree( line ); int total = 0, multiple = 0, pplus = 0; if ( root != NULL ) { node *u = node_children(root); const char *p = line; node *next_u = NULL; while(*p) { next_u = NULL; while(u != NULL) { int nstart = node_start(u); if (line[nstart] == *p) { int end = node_end(u,e); pplus = end - nstart + (line[end] == 0 ? 0 : 1); next_u = node_children(u); } else if (node_is_leaf(u)){ multiple++; } else { multiple += node_num_children(node_children(u)); } u = node_next(u); } total += (p - line) * multiple; p += pplus; u = next_u; multiple = 0; } total += (p - line); node_dispose( root ); } return total; }
int node_num_children(node* sibling) { int result = 0; while(sibling != NULL) { if (node_is_leaf(sibling)) { result++; } else { result += node_num_children(node_children(sibling)); } sibling = node_next(sibling); } return result; }
/** * Set the length of each leaf to e recursively * @param v the node in question * @param log the log to record errors in */ static void set_e( suffixtree *st, node *v, plugin_log *log ) { if ( node_is_leaf(v) ) { node_set_len( v, st->e-node_start(v)+1 ); } node_iterator *iter = node_children( v, log ); if ( iter != NULL ) { while ( node_iterator_has_next(iter) ) { node *u = node_iterator_next( iter ); set_e( st, u, log ); } node_iterator_dispose( iter ); } }
/** * Create a hashtable by conversion from a list of child-nodes * @param children add these nodes to the hashtable for starters * @return an initialised hashtable */ hashtable *hashtable_create( node *parent ) { hashtable *ht = calloc( 1, sizeof(hashtable) ); if ( ht != NULL ) { int nnodes = node_num_children( parent ); mem_usage += sizeof(hashtable); ht->nbuckets = nnodes*2; ht->items = calloc( ht->nbuckets, sizeof(struct bucket*) ); if ( ht->items != NULL ) { int res = 1; mem_usage += ht->nbuckets*sizeof(struct bucket*); node_iterator *iter = node_children( parent ); if ( iter != NULL ) { while ( res && node_iterator_has_next(iter) ) { node *temp = node_iterator_next( iter ); node_clear_next( temp ); res = hashtable_add( ht, temp ); } node_iterator_dispose( iter ); } else res = 0; if ( !res ) { hashtable_dispose( ht ); ht = NULL; } } else fprintf(stderr,"failed to allocate %d buckets\n",ht->nbuckets); } else fprintf(stderr,"hashtable: failed to allocate\n"); return ht; }