diff --git a/include/node.h b/include/node.h index 8386471..f168a30 100644 --- a/include/node.h +++ b/include/node.h @@ -13,6 +13,35 @@ #include #include +#include "token.h" + +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); + +rnode * rnode_find_edge(rnode * n, char * pat); + +void rnode_append_child(rnode *n, rnode *child); + + + + +void rnode_append_route(rnode * tree, token_array * token); #endif /* !NODE_H */ diff --git a/include/token.h b/include/token.h index 3d37029..9df8fa1 100644 --- a/include/token.h +++ b/include/token.h @@ -33,4 +33,8 @@ void token_array_dump(token_array *l); token_array * split_route_pattern(char *pattern, int pattern_len); +#define token_array_fetch(t,i) t->tokens[i] +#define token_array_len(t) t->len +#define token_array_cap(t) t->cap + #endif /* !TOKEN_H */ diff --git a/src/node.c b/src/node.c index 5c92a4a..48204cc 100644 --- a/src/node.c +++ b/src/node.c @@ -6,7 +6,76 @@ // Jemalloc memory management #include +// PCRE +#include + // Judy array #include +#include "node.h" +#include "token.h" + // 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_len = 0; + n->children_cap = 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 ]); + } + free(tree->children); + 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) { + // find the same sub-pattern, if it does not exist, create one + + rnode * c = rnode_find_edge(n, pat); + if (c) { + return FALSE; + } + + + token_array_append(n->edge_patterns, pat); + rnode_append_child(n, child); + + assert( token_array_len(n->edge_patterns) == n->children_len ); + return TRUE; +} + + +void rnode_append_child(rnode *n, rnode *child) { + if (n->children_len >= n->children_cap) { + n->children_cap *= 2; + n->children = realloc(n->children, n->children_cap); + } + n->children[ n->children_len++ ] = child; +} + + +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]; + } + } + return NULL; +} + +void rnode_append_route(rnode * tree, token_array * tokens) { + +} diff --git a/src/token.c b/src/token.c index 8547bce..b50d2ac 100644 --- a/src/token.c +++ b/src/token.c @@ -19,6 +19,14 @@ token_array * token_array_create(int cap) { return list; } +void token_array_free(token_array *l) { + for ( int i = 0; i < l->len ; i++ ) { + char * t = l->tokens[ i ]; + free(t); + } + free(l); +} + bool token_array_is_full(token_array * l) { return l->len >= l->cap; } @@ -51,13 +59,6 @@ void token_array_dump(token_array *l) { printf("]\n"); } -void token_array_free(token_array *l) { - for ( int i = 0; i < l->len ; i++ ) { - char * t = l->tokens[ i ]; - free(t); - } - free(l); -} diff --git a/tests/test_tree.c b/tests/test_tree.c index d899c11..36f0dc1 100644 --- a/tests/test_tree.c +++ b/tests/test_tree.c @@ -11,8 +11,36 @@ START_TEST (test_ltrim_slash) } END_TEST +START_TEST (test_rnode_construct_uniq) +{ + rnode * n = rnode_create(10); -START_TEST (test_route) + 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 ); + + rnode_free(n); +} +END_TEST + +START_TEST (test_rnode_find_edge) +{ + rnode * n = rnode_create(10); + + rnode * child = rnode_create(3); + + fail_if( rnode_add_edge(n, strdup("/add") , child) == FALSE ); + + 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; @@ -75,9 +103,11 @@ Suite* r3_suite (void) { Suite *suite = suite_create("blah"); TCase *tcase = tcase_create("testcase"); - tcase_add_test(tcase, test_route); + tcase_add_test(tcase, test_route_split); tcase_add_test(tcase, test_token_array); tcase_add_test(tcase, test_ltrim_slash); + tcase_add_test(tcase, test_rnode_construct_uniq); + tcase_add_test(tcase, test_rnode_find_edge); suite_add_tcase(suite, tcase);