allocate ov space when compiling the tree

This commit is contained in:
c9s 2014-05-16 20:58:30 +08:00
parent 40e927a4f1
commit 2381f54dc4
4 changed files with 51 additions and 36 deletions

View file

@ -27,8 +27,8 @@ typedef struct _node node;
struct _node { struct _node {
edge ** edges; edge ** edges;
int r3_edge_len; int edge_len;
int r3_edge_cap; int edge_cap;
/** compile-time variables here.... **/ /** compile-time variables here.... **/
@ -39,7 +39,7 @@ struct _node {
pcre * pcre_pattern; pcre * pcre_pattern;
pcre_extra * pcre_extra; pcre_extra * pcre_extra;
int ov_cnt; int ov_cnt;
int * ov;
/** /**
* the pointer of route structure * the pointer of route structure

View file

@ -36,7 +36,7 @@ void r3_edge_branch(edge *e, int dl) {
int s1_len = 0; int s1_len = 0;
edge **tmp_edges = e->child->edges; 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 // the suffix edge of the leaf
c1 = r3_tree_create(3); 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]); r3_tree_append_edge(c1, tmp_edges[i]);
e->child->edges[i] = NULL; e->child->edges[i] = NULL;
} }
e->child->r3_edge_len = 0; e->child->edge_len = 0;
e->child->endpoint--; e->child->endpoint--;
info("branched pattern: %s\n", e1->pattern); info("branched pattern: %s\n", e1->pattern);

View file

@ -27,18 +27,19 @@ node * r3_tree_create(int cap) {
node * n = (node*) malloc( sizeof(node) ); node * n = (node*) malloc( sizeof(node) );
n->edges = (edge**) malloc( sizeof(edge*) * 10 ); n->edges = (edge**) malloc( sizeof(edge*) * 10 );
n->r3_edge_len = 0; n->edge_len = 0;
n->r3_edge_cap = cap; n->edge_cap = cap;
n->endpoint = 0; n->endpoint = 0;
n->combined_pattern = NULL; n->combined_pattern = NULL;
n->pcre_pattern = NULL; n->pcre_pattern = NULL;
n->pcre_extra = NULL; n->pcre_extra = NULL;
n->ov_cnt = 0; n->ov_cnt = 0;
n->ov = NULL;
return n; return n;
} }
void r3_tree_free(node * tree) { 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]) { if (tree->edges[i]) {
r3_edge_free(tree->edges[ i ]); r3_edge_free(tree->edges[ i ]);
} }
@ -46,9 +47,14 @@ void r3_tree_free(node * tree) {
if (tree->combined_pattern) if (tree->combined_pattern)
free(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); free(tree->edges);
// str_array_free(tree->r3_edge_patterns); // str_array_free(tree->edge_patterns);
free(tree); free(tree);
tree = NULL; 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); e = r3_edge_create( pat, strlen(pat), child);
r3_tree_append_edge(n, e); r3_tree_append_edge(n, e);
// str_array_append(n->r3_edge_patterns, pat); // str_array_append(n->edge_patterns, pat);
// assert( str_array_len(n->r3_edge_patterns) == n->r3_edge_len ); // assert( str_array_len(n->edge_patterns) == n->edge_len );
return e; 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) { void r3_tree_append_edge(node *n, edge *e) {
if (!n->edges) { if (!n->edges) {
n->r3_edge_cap = 3; n->edge_cap = 3;
n->edges = malloc(sizeof(edge) * n->r3_edge_cap); n->edges = malloc(sizeof(edge) * n->edge_cap);
} }
if (n->r3_edge_len >= n->r3_edge_cap) { if (n->edge_len >= n->edge_cap) {
n->r3_edge_cap *= 2; n->edge_cap *= 2;
n->edges = realloc(n->edges, sizeof(edge) * n->r3_edge_cap); 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 * r3_node_find_edge(node * n, char * pat) {
edge * e; 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 = n->edges[i];
if ( strcmp(e->pattern, pat) == 0 ) { if ( strcmp(e->pattern, pat) == 0 ) {
return e; return e;
@ -109,7 +115,7 @@ void r3_tree_compile(node *n)
n->combined_pattern = NULL; 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); r3_tree_compile(n->edges[i]->child);
} }
} }
@ -133,7 +139,7 @@ void r3_tree_compile_patterns(node * n) {
p++; p++;
edge *e = NULL; 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]; e = n->edges[i];
if ( e->has_slug ) { if ( e->has_slug ) {
char * slug_pat = compile_slug(e->pattern, e->pattern_len); char * slug_pat = compile_slug(e->pattern, e->pattern_len);
@ -147,13 +153,16 @@ void r3_tree_compile_patterns(node * n) {
strncat(p++,")", 1); strncat(p++,")", 1);
} }
if ( i + 1 < n->r3_edge_len ) { if ( i + 1 < n->edge_len ) {
strncat(p++,"|",1); 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 = cpat;
n->combined_pattern_len = p - 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 // pcre pattern node, we use pcre_exec to match the nodes
if (n->pcre_pattern) { if (n->pcre_pattern) {
info("pcre matching %s on %s\n", n->combined_pattern, path); info("pcre matching %s on %s\n", n->combined_pattern, path);
int ovector[n->ov_cnt];
int rc; int rc;
int i; 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 */ path_len, /* the length of the subject */
0, /* start at offset 0 in the subject */ 0, /* start at offset 0 in the subject */
0, /* default options */ 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 */ n->ov_cnt); /* number of elements in the output vector */
info("rc: %d\n", rc ); 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++) for (i = 1; i < rc; i++)
{ {
char *substring_start = path + ovector[2*i]; char *substring_start = path + n->ov[2*i];
int substring_length = ovector[2*i+1] - ovector[2*i]; int substring_length = n->ov[2*i+1] - n->ov[2*i];
info("%2d: %.*s\n", i, substring_length, substring_start); info("%2d: %.*s\n", i, substring_length, substring_start);
if ( substring_length > 0) { if ( substring_length > 0) {
int restlen = path_len - ovector[2*i+1]; // fully match to the end 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->r3_edge_len, i); info("matched item => restlen:%d edges:%d i:%d\n", restlen, n->edge_len, i);
e = n->edges[i - 1]; 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) { inline edge * r3_node_find_edge_str(node * n, char * str, int str_len) {
int i = 0; 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) ); 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 ) { if ( strncmp( node_edge_pattern(n,i), str, node_edge_pattern_len(n,i) ) == 0 ) {
return n->edges[i]; return n->edges[i];
@ -324,8 +332,8 @@ node * r3_tree_lookup(node * tree, char * path, int path_len) {
node * r3_node_create() { node * r3_node_create() {
node * n = (node*) malloc( sizeof(node) ); node * n = (node*) malloc( sizeof(node) );
n->edges = NULL; n->edges = NULL;
n->r3_edge_len = 0; n->edge_len = 0;
n->r3_edge_cap = 0; n->edge_cap = 0;
n->endpoint = 0; n->endpoint = 0;
n->combined_pattern = NULL; n->combined_pattern = NULL;
n->pcre_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 */ /* length of common prefix */
int dl = 0; 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); 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 ); // 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 r3_node_has_slug_edges(node *n) {
bool found = FALSE; bool found = FALSE;
edge *e; 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 = n->edges[i];
e->has_slug = contains_slug(e->pattern); e->has_slug = contains_slug(e->pattern);
if (e->has_slug) if (e->has_slug)
@ -444,14 +452,14 @@ bool r3_node_has_slug_edges(node *n) {
void r3_tree_dump(node * n, int level) { void r3_tree_dump(node * n, int level) {
if ( n->r3_edge_len ) { if ( n->edge_len ) {
if ( n->combined_pattern ) { if ( n->combined_pattern ) {
printf(" regexp:%s", n->combined_pattern); printf(" regexp:%s", n->combined_pattern);
} }
printf(" endpoint:%d\n", n->endpoint); 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]; edge * e = n->edges[i];
print_indent(level); print_indent(level);
printf(" |-\"%s\"", e->pattern); printf(" |-\"%s\"", e->pattern);

View file

@ -26,3 +26,10 @@
1400244648,5978607.43 1400244648,5978607.43
1400244653,5956364.63 1400244653,5956364.63
1400244657,5911318.61 1400244657,5911318.61
1400244829,6362496.45
1400244887,6330902.59
1400244895,6390983.42
1400244908,6380415.58
1400244914,6346830.19
1400244932,6610181.08
1400245102,6404550.11

1 1400242718 5649455.80
26 1400244648 5978607.43
27 1400244653 5956364.63
28 1400244657 5911318.61
29 1400244829 6362496.45
30 1400244887 6330902.59
31 1400244895 6390983.42
32 1400244908 6380415.58
33 1400244914 6346830.19
34 1400244932 6610181.08
35 1400245102 6404550.11