From 2348387f3cb26221efc1024cfb162e76e6a538eb Mon Sep 17 00:00:00 2001 From: c9s Date: Thu, 15 May 2014 18:02:10 +0800 Subject: [PATCH] more tests --- include/node.h | 23 +++++----- include/str.h | 5 +++ src/node.c | 108 ++++++++++++++++++++++++++++++++++++---------- src/str.c | 13 ++++++ tests/test_tree.c | 43 ++++++++++++++++-- 5 files changed, 154 insertions(+), 38 deletions(-) diff --git a/include/node.h b/include/node.h index f168a30..b5c80e8 100644 --- a/include/node.h +++ b/include/node.h @@ -15,33 +15,32 @@ #include "token.h" +struct _redge; +struct _rnode; +typedef struct _redge redge; typedef struct _rnode rnode; -struct _rnode { - rnode ** children; - int children_len; - int children_cap; - /* the combined regexp pattern string from pattern_tokens */ - char* combined_pattern; - token_array * edge_patterns; -}; rnode * rnode_create(int cap); void rnode_free(rnode * tree); -bool rnode_add_edge(rnode * n, char * pat , rnode *child); +void redge_free(redge * edge); -rnode * rnode_find_edge(rnode * n, char * pat); +bool rnode_add_child(rnode * n, char * pat , rnode *child); -void rnode_append_child(rnode *n, rnode *child); +redge * rnode_find_edge(rnode * n, char * pat); +void rnode_append_edge(rnode *n, redge *child); +rnode * rnode_insert_tokens(rnode * tree, token_array * tokens); +void rnode_dump(rnode * n, int level); -void rnode_append_route(rnode * tree, token_array * token); +redge * redge_create(char * pattern, int pattern_len, rnode * child); +void redge_free(redge * edge); #endif /* !NODE_H */ diff --git a/include/str.h b/include/str.h index e1f9411..46ec218 100644 --- a/include/str.h +++ b/include/str.h @@ -11,4 +11,9 @@ char * ltrim_slash(char* str); char** str_split(char* a_str, const char a_delim); +void str_repeat(char *s, char *c, int len); + +void print_indent(int level); + #endif /* !STR_H */ + diff --git a/src/node.c b/src/node.c index 48204cc..42459db 100644 --- a/src/node.c +++ b/src/node.c @@ -15,67 +15,129 @@ #include "node.h" #include "token.h" +struct _rnode { + redge ** children; + int children_len; + int children_cap; + + /* the combined regexp pattern string from pattern_tokens */ + char* combined_pattern; +}; + +struct _redge { + char * pattern; + int pattern_len; + rnode * child; +}; + // String value as the index http://judy.sourceforge.net/doc/JudySL_3x.htm rnode * rnode_create(int cap) { rnode * n = (rnode*) calloc( sizeof(rnode) , 1); - n->children = (rnode**) malloc( sizeof(rnode*) * 10 ); + n->children = (redge**) malloc( sizeof(redge*) * 10 ); n->children_len = 0; n->children_cap = 10; - - n->edge_patterns = token_array_create(10); + // n->edge_patterns = token_array_create(10); return n; } void rnode_free(rnode * tree) { for (int i = 0 ; i < tree->children_len ; i++ ) { - rnode_free(tree->children[ i ]); + redge_free(tree->children[ i ]); } free(tree->children); - token_array_free(tree->edge_patterns); + // token_array_free(tree->edge_patterns); free(tree); tree = NULL; } + /* parent node, edge pattern, child */ -bool rnode_add_edge(rnode * n, char * pat , rnode *child) { +bool rnode_add_child(rnode * n, char * pat , rnode *child) { // find the same sub-pattern, if it does not exist, create one - rnode * c = rnode_find_edge(n, pat); - if (c) { + redge * e; + + e = rnode_find_edge(n, pat); + if (e) { return FALSE; } - - token_array_append(n->edge_patterns, pat); - rnode_append_child(n, child); - - assert( token_array_len(n->edge_patterns) == n->children_len ); + e = redge_create( pat, strlen(pat), child); + rnode_append_edge(n, e); + // token_array_append(n->edge_patterns, pat); + // assert( token_array_len(n->edge_patterns) == n->children_len ); return TRUE; } -void rnode_append_child(rnode *n, rnode *child) { + +void rnode_append_edge(rnode *n, redge *e) { if (n->children_len >= n->children_cap) { n->children_cap *= 2; - n->children = realloc(n->children, n->children_cap); + n->children = realloc(n->children, sizeof(redge) * n->children_cap); } - n->children[ n->children_len++ ] = child; + n->children[ n->children_len++ ] = e; } -rnode * rnode_find_edge(rnode * n, char * pat) { - for (int i = 0 ; i < n->edge_patterns->len ; i++ ) { - char * edge_pat = token_array_fetch( n->edge_patterns, i ); - if (strcmp(edge_pat, pat) == 0 ) { - return n->children[i]; +redge * rnode_find_edge(rnode * n, char * pat) { + redge * e; + for (int i = 0 ; i < n->children_len ; i++ ) { + e = n->children[i]; + if ( strcmp(e->pattern, pat) == 0 ) { + return e; } } return NULL; } -void rnode_append_route(rnode * tree, token_array * tokens) { - +rnode * rnode_insert_tokens(rnode * tree, token_array * tokens) { + rnode * n = tree; + redge * e = NULL; + for ( int i = 0 ; i < tokens->len ; i++ ) { + e = rnode_find_edge(n, token_array_fetch(tokens, i) ); + if (e) { + n = e->child; + continue; + } + // insert node + rnode * child = rnode_create(3); + rnode_add_child(n, token_array_fetch(tokens,i) , child); + n = child; + } + return n; } + +void rnode_dump(rnode * n, int level) { + if ( n->children_len ) { + print_indent(level); + printf("*\n"); + for ( int i = 0 ; i < n->children_len ; i++ ) { + redge * e = n->children[i]; + print_indent(level + 1); + printf("+ \"%s\"\n", e->pattern); + rnode_dump( e->child, level + 1); + } + } +} + +redge * redge_create(char * pattern, int pattern_len, rnode * child) { + redge * edge = (redge*) malloc( sizeof(redge) ); + edge->pattern = pattern; + edge->pattern_len = pattern_len; + edge->child = child; + return edge; +} + +void redge_free(redge * e) { + free(e->pattern); + if ( e->child ) { + rnode_free(e->child); + } +} + + + diff --git a/src/str.c b/src/str.c index 399a0ed..1585151 100644 --- a/src/str.c +++ b/src/str.c @@ -67,3 +67,16 @@ char** str_split(char* a_str, const char a_delim) return result; } + +void str_repeat(char *s, char *c, int len) { + while(len--) { + s[len - 1] = *c; + } +} + +void print_indent(int level) { + int len = level * 2; + while(len--) { + printf(" "); + } +} diff --git a/tests/test_tree.c b/tests/test_tree.c index 36f0dc1..d0511c8 100644 --- a/tests/test_tree.c +++ b/tests/test_tree.c @@ -17,8 +17,8 @@ START_TEST (test_rnode_construct_uniq) rnode * child = rnode_create(3); - fail_if( rnode_add_edge(n, strdup("/add") , child) == FALSE ); - fail_if( rnode_add_edge(n, strdup("/add") , child) != FALSE ); + fail_if( rnode_add_child(n, strdup("/add") , child) == FALSE ); + fail_if( rnode_add_child(n, strdup("/add") , child) != FALSE ); rnode_free(n); } @@ -30,7 +30,7 @@ START_TEST (test_rnode_find_edge) rnode * child = rnode_create(3); - fail_if( rnode_add_edge(n, strdup("/add") , child) == FALSE ); + fail_if( rnode_add_child(n, strdup("/add") , child) == FALSE ); fail_if( rnode_find_edge(n, "/add") == NULL ); fail_if( rnode_find_edge(n, "/bar") != NULL ); @@ -40,6 +40,42 @@ START_TEST (test_rnode_find_edge) END_TEST +START_TEST (test_rnode_insert_tokens) +{ + token_array *t; + + rnode * n = rnode_create(10); + + fail_if(n == NULL, "rnode tree"); + + t = split_route_pattern("/foo/bar", strlen("/foo/bar") ); + fail_if( rnode_insert_tokens(n , t) == NULL ); + + t = split_route_pattern("/foo/zoo", strlen("/foo/zoo") ); + fail_if( rnode_insert_tokens(n , t) == NULL ); + + t = split_route_pattern("/a/bb", strlen("/a/bb") ); + fail_if( rnode_insert_tokens(n , t) == NULL ); + + t = split_route_pattern("/a/bb/cc", strlen("/a/bb/cc") ); + fail_if( rnode_insert_tokens(n , t) == NULL ); + + t = split_route_pattern("/a/jj/kk", strlen("/a/jj/kk") ); + fail_if( rnode_insert_tokens(n , t) == NULL ); + + rnode_dump(n, 0); + + + // fail_if( rnode_find_edge(n, "/add") == NULL ); + // fail_if( rnode_find_edge(n, "/bar") != NULL ); + + rnode_free(n); +} +END_TEST + + + + START_TEST (test_route_split) { token_array *t; @@ -108,6 +144,7 @@ Suite* r3_suite (void) { tcase_add_test(tcase, test_ltrim_slash); tcase_add_test(tcase, test_rnode_construct_uniq); tcase_add_test(tcase, test_rnode_find_edge); + tcase_add_test(tcase, test_rnode_insert_tokens); suite_add_tcase(suite, tcase);