From 2381f54dc47828d8ccd34d733e8a0ec1366c2293 Mon Sep 17 00:00:00 2001 From: c9s Date: Fri, 16 May 2014 20:58:30 +0800 Subject: [PATCH] allocate ov space when compiling the tree --- include/r3.h | 6 ++-- src/edge.c | 4 +-- src/node.c | 70 +++++++++++++++++++++++++-------------------- tests/bench_str.csv | 7 +++++ 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/include/r3.h b/include/r3.h index f8a0189..817a24b 100644 --- a/include/r3.h +++ b/include/r3.h @@ -27,8 +27,8 @@ typedef struct _node node; struct _node { edge ** edges; - int r3_edge_len; - int r3_edge_cap; + int edge_len; + int edge_cap; /** compile-time variables here.... **/ @@ -39,7 +39,7 @@ struct _node { pcre * pcre_pattern; pcre_extra * pcre_extra; int ov_cnt; - + int * ov; /** * the pointer of route structure diff --git a/src/edge.c b/src/edge.c index bb6b60b..1489cb7 100644 --- a/src/edge.c +++ b/src/edge.c @@ -36,7 +36,7 @@ void r3_edge_branch(edge *e, int dl) { int s1_len = 0; edge **tmp_edges = e->child->edges; - int tmp_r3_edge_len = e->child->r3_edge_len; + int tmp_r3_edge_len = e->child->edge_len; // the suffix edge of the leaf c1 = r3_tree_create(3); @@ -49,7 +49,7 @@ void r3_edge_branch(edge *e, int dl) { r3_tree_append_edge(c1, tmp_edges[i]); e->child->edges[i] = NULL; } - e->child->r3_edge_len = 0; + e->child->edge_len = 0; e->child->endpoint--; info("branched pattern: %s\n", e1->pattern); diff --git a/src/node.c b/src/node.c index 4830c98..a48dd67 100644 --- a/src/node.c +++ b/src/node.c @@ -27,18 +27,19 @@ node * r3_tree_create(int cap) { node * n = (node*) malloc( sizeof(node) ); n->edges = (edge**) malloc( sizeof(edge*) * 10 ); - n->r3_edge_len = 0; - n->r3_edge_cap = cap; + n->edge_len = 0; + n->edge_cap = cap; n->endpoint = 0; n->combined_pattern = NULL; n->pcre_pattern = NULL; n->pcre_extra = NULL; n->ov_cnt = 0; + n->ov = NULL; return n; } void r3_tree_free(node * tree) { - for (int i = 0 ; i < tree->r3_edge_len ; i++ ) { + for (int i = 0 ; i < tree->edge_len ; i++ ) { if (tree->edges[i]) { r3_edge_free(tree->edges[ i ]); } @@ -46,9 +47,14 @@ void r3_tree_free(node * tree) { if (tree->combined_pattern) free(tree->combined_pattern); - + if (tree->pcre_pattern) + free(tree->pcre_pattern); + if (tree->pcre_extra) + free(tree->pcre_extra); + if (tree->ov) + free(tree->ov); free(tree->edges); - // str_array_free(tree->r3_edge_patterns); + // str_array_free(tree->edge_patterns); free(tree); tree = NULL; } @@ -68,8 +74,8 @@ edge * r3_tree_add_child(node * n, char * pat , node *child) { e = r3_edge_create( pat, strlen(pat), child); r3_tree_append_edge(n, e); - // str_array_append(n->r3_edge_patterns, pat); - // assert( str_array_len(n->r3_edge_patterns) == n->r3_edge_len ); + // str_array_append(n->edge_patterns, pat); + // assert( str_array_len(n->edge_patterns) == n->edge_len ); return e; } @@ -78,19 +84,19 @@ edge * r3_tree_add_child(node * n, char * pat , node *child) { void r3_tree_append_edge(node *n, edge *e) { if (!n->edges) { - n->r3_edge_cap = 3; - n->edges = malloc(sizeof(edge) * n->r3_edge_cap); + n->edge_cap = 3; + n->edges = malloc(sizeof(edge) * n->edge_cap); } - if (n->r3_edge_len >= n->r3_edge_cap) { - n->r3_edge_cap *= 2; - n->edges = realloc(n->edges, sizeof(edge) * n->r3_edge_cap); + if (n->edge_len >= n->edge_cap) { + n->edge_cap *= 2; + n->edges = realloc(n->edges, sizeof(edge) * n->edge_cap); } - n->edges[ n->r3_edge_len++ ] = e; + n->edges[ n->edge_len++ ] = e; } edge * r3_node_find_edge(node * n, char * pat) { edge * e; - for (int i = 0 ; i < n->r3_edge_len ; i++ ) { + for (int i = 0 ; i < n->edge_len ; i++ ) { e = n->edges[i]; if ( strcmp(e->pattern, pat) == 0 ) { return e; @@ -109,7 +115,7 @@ void r3_tree_compile(node *n) n->combined_pattern = NULL; } - for (int i = 0 ; i < n->r3_edge_len ; i++ ) { + for (int i = 0 ; i < n->edge_len ; i++ ) { r3_tree_compile(n->edges[i]->child); } } @@ -133,7 +139,7 @@ void r3_tree_compile_patterns(node * n) { p++; edge *e = NULL; - for ( int i = 0 ; i < n->r3_edge_len ; i++ ) { + for ( int i = 0 ; i < n->edge_len ; i++ ) { e = n->edges[i]; if ( e->has_slug ) { char * slug_pat = compile_slug(e->pattern, e->pattern_len); @@ -147,13 +153,16 @@ void r3_tree_compile_patterns(node * n) { strncat(p++,")", 1); } - if ( i + 1 < n->r3_edge_len ) { + if ( i + 1 < n->edge_len ) { strncat(p++,"|",1); } } - n->ov_cnt = (1 + n->r3_edge_len) * 3; + n->ov_cnt = (1 + n->edge_len) * 3; + n->ov = (int*) calloc(sizeof(int), n->ov_cnt); + + n->combined_pattern = cpat; n->combined_pattern_len = p - cpat; @@ -222,7 +231,6 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { // pcre pattern node, we use pcre_exec to match the nodes if (n->pcre_pattern) { info("pcre matching %s on %s\n", n->combined_pattern, path); - int ovector[n->ov_cnt]; int rc; int i; @@ -235,7 +243,7 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { path_len, /* the length of the subject */ 0, /* start at offset 0 in the subject */ 0, /* default options */ - ovector, /* output vector for substring information */ + n->ov, /* output vector for substring information */ n->ov_cnt); /* number of elements in the output vector */ info("rc: %d\n", rc ); @@ -254,13 +262,13 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { for (i = 1; i < rc; i++) { - char *substring_start = path + ovector[2*i]; - int substring_length = ovector[2*i+1] - ovector[2*i]; + char *substring_start = path + n->ov[2*i]; + int substring_length = n->ov[2*i+1] - n->ov[2*i]; info("%2d: %.*s\n", i, substring_length, substring_start); if ( substring_length > 0) { - int restlen = path_len - ovector[2*i+1]; // fully match to the end - info("matched item => restlen:%d edges:%d i:%d\n", restlen, n->r3_edge_len, i); + int restlen = path_len - n->ov[2*i+1]; // fully match to the end + info("matched item => restlen:%d edges:%d i:%d\n", restlen, n->edge_len, i); e = n->edges[i - 1]; @@ -293,7 +301,7 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { inline edge * r3_node_find_edge_str(node * n, char * str, int str_len) { int i = 0; - for (; i < n->r3_edge_len ; i++ ) { + for (; i < n->edge_len ; i++ ) { info("matching '%s' with '%s'\n", str, node_edge_pattern(n,i) ); if ( strncmp( node_edge_pattern(n,i), str, node_edge_pattern_len(n,i) ) == 0 ) { return n->edges[i]; @@ -324,8 +332,8 @@ node * r3_tree_lookup(node * tree, char * path, int path_len) { node * r3_node_create() { node * n = (node*) malloc( sizeof(node) ); n->edges = NULL; - n->r3_edge_len = 0; - n->r3_edge_cap = 0; + n->edge_len = 0; + n->edge_cap = 0; n->endpoint = 0; n->combined_pattern = NULL; n->pcre_pattern = NULL; @@ -347,7 +355,7 @@ node * r3_tree_insert_pathn(node *tree, char *route, int route_len, void * route /* length of common prefix */ int dl = 0; - for( int i = 0 ; i < n->r3_edge_len ; i++ ) { + for( int i = 0 ; i < n->edge_len ; i++ ) { dl = strndiff(route, n->edges[i]->pattern, n->edges[i]->pattern_len); // printf("dl: %d %s vs %s\n", dl, route, n->edges[i]->pattern ); @@ -432,7 +440,7 @@ node * r3_tree_insert_pathn(node *tree, char *route, int route_len, void * route bool r3_node_has_slug_edges(node *n) { bool found = FALSE; edge *e; - for ( int i = 0 ; i < n->r3_edge_len ; i++ ) { + for ( int i = 0 ; i < n->edge_len ; i++ ) { e = n->edges[i]; e->has_slug = contains_slug(e->pattern); if (e->has_slug) @@ -444,14 +452,14 @@ bool r3_node_has_slug_edges(node *n) { void r3_tree_dump(node * n, int level) { - if ( n->r3_edge_len ) { + if ( n->edge_len ) { if ( n->combined_pattern ) { printf(" regexp:%s", n->combined_pattern); } printf(" endpoint:%d\n", n->endpoint); - for ( int i = 0 ; i < n->r3_edge_len ; i++ ) { + for ( int i = 0 ; i < n->edge_len ; i++ ) { edge * e = n->edges[i]; print_indent(level); printf(" |-\"%s\"", e->pattern); diff --git a/tests/bench_str.csv b/tests/bench_str.csv index 5b263e2..9f447a8 100644 --- a/tests/bench_str.csv +++ b/tests/bench_str.csv @@ -26,3 +26,10 @@ 1400244648,5978607.43 1400244653,5956364.63 1400244657,5911318.61 +1400244829,6362496.45 +1400244887,6330902.59 +1400244895,6390983.42 +1400244908,6380415.58 +1400244914,6346830.19 +1400244932,6610181.08 +1400245102,6404550.11