Fix endpoint when branching edges

This commit is contained in:
c9s 2014-05-21 01:15:54 +08:00
parent 99198297c2
commit e9797295b5
4 changed files with 58 additions and 21 deletions

View file

@ -55,7 +55,6 @@ node * r3_edge_branch(edge *e, int dl) {
new_child = r3_tree_create(3); new_child = r3_tree_create(3);
s1_len = e->pattern_len - dl; s1_len = e->pattern_len - dl;
e1 = r3_edge_create(strndup(s1, s1_len), s1_len, new_child); e1 = r3_edge_create(strndup(s1, s1_len), s1_len, new_child);
// printf("edge left: %s\n", e1->pattern);
// Migrate the child edges to the new edge we just created. // Migrate the child edges to the new edge we just created.
for ( int i = 0 ; i < tmp_edge_len ; i++ ) { for ( int i = 0 ; i < tmp_edge_len ; i++ ) {
@ -63,12 +62,10 @@ node * r3_edge_branch(edge *e, int dl) {
e->child->edges[i] = NULL; e->child->edges[i] = NULL;
} }
e->child->edge_len = 0; e->child->edge_len = 0;
e->child->endpoint--; new_child->endpoint = e->child->endpoint;
e->child->endpoint = 0; // reset endpoint
// info("branched pattern: %s\n", e1->pattern);
r3_node_append_edge(e->child, e1); r3_node_append_edge(e->child, e1);
new_child->endpoint++;
new_child->data = e->child->data; // copy data pointer new_child->data = e->child->data; // copy data pointer
e->child->data = NULL; e->child->data = NULL;

View file

@ -308,7 +308,7 @@ node * r3_tree_matchl(node * n, char * path, int path_len, match_entry * entry)
str_array_append(entry->vars , strndup(substring_start, substring_length)); str_array_append(entry->vars , strndup(substring_start, substring_length));
} }
if (restlen == 0 ) { if (restlen == 0 ) {
return e->child && e->child->endpoint ? e->child : NULL; return e->child && e->child->endpoint > 0 ? e->child : NULL;
} }
// get the length of orginal string: $0 // get the length of orginal string: $0
return r3_tree_matchl( e->child, path + (n->ov[1] - n->ov[0]), restlen, entry); return r3_tree_matchl( e->child, path + (n->ov[1] - n->ov[0]), restlen, entry);
@ -321,7 +321,7 @@ node * r3_tree_matchl(node * n, char * path, int path_len, match_entry * entry)
if ( (e = r3_node_find_edge_str(n, path, path_len)) != NULL ) { if ( (e = r3_node_find_edge_str(n, path, path_len)) != NULL ) {
int restlen = path_len - e->pattern_len; int restlen = path_len - e->pattern_len;
if (restlen == 0) { if (restlen == 0) {
return e->child && e->child->endpoint ? e->child : NULL; return e->child && e->child->endpoint > 0 ? e->child : NULL;
} }
return r3_tree_matchl(e->child, path + e->pattern_len, restlen, entry); return r3_tree_matchl(e->child, path + e->pattern_len, restlen, entry);
} }
@ -459,6 +459,7 @@ node * r3_tree_insert_pathl_(node *tree, char *path, int path_len, route * route
// insert the first one edge, and break at "p" // insert the first one edge, and break at "p"
node * child = r3_tree_create(3); node * child = r3_tree_create(3);
r3_node_add_child(n, strndup(path, (int)(p - path)), child); r3_node_add_child(n, strndup(path, (int)(p - path)), child);
child->endpoint = 0;
// and insert the rest part to the child // and insert the rest part to the child
return r3_tree_insert_pathl_(child, p, path_len - (int)(p - path), route, data); return r3_tree_insert_pathl_(child, p, path_len - (int)(p - path), route, data);
@ -487,7 +488,7 @@ node * r3_tree_insert_pathl_(node *tree, char *path, int path_len, route * route
// there are no more path to insert // there are no more path to insert
// see if there is an endpoint already // see if there is an endpoint already
if (e->child->endpoint) { if (e->child->endpoint > 0) {
// XXX: return an error code instead of NULL // XXX: return an error code instead of NULL
return NULL; return NULL;
} }
@ -501,9 +502,6 @@ node * r3_tree_insert_pathl_(node *tree, char *path, int path_len, route * route
} }
} else if ( prefix_len < e->pattern_len ) { } else if ( prefix_len < e->pattern_len ) {
// printf("branch the edge prefix_len: %d\n", prefix_len);
/* it's partially matched with the pattern, /* it's partially matched with the pattern,
* we should split the end point and make a branch here... * we should split the end point and make a branch here...
*/ */
@ -534,6 +532,9 @@ bool r3_node_has_slug_edges(node *n) {
void r3_tree_dump(node * n, int level) { void r3_tree_dump(node * n, int level) {
print_indent(level); print_indent(level);
printf("(o)");
if ( n->combined_pattern ) { if ( n->combined_pattern ) {
printf(" regexp:%s", n->combined_pattern); printf(" regexp:%s", n->combined_pattern);
} }

View file

@ -401,3 +401,25 @@
1400604504,13787120.46 1400604504,13787120.46
1400604527,13505264.87 1400604527,13505264.87
1400604546,13522321.17 1400604546,13522321.17
1400605108,13746963.64
1400605113,13899221.05
1400605117,13066929.36
1400605122,13818325.58
1400605132,13624101.24
1400605227,12992570.34
1400605241,13631407.12
1400605247,13773296.72
1400605254,13601113.09
1400605334,13477173.69
1400605341,13528406.95
1400605371,13822120.38
1400605378,13627925.89
1400605452,13704460.37
1400605482,13612516.46
1400605625,12647482.46
1400605676,13671799.76
1400605706,13269956.01
1400605735,13684822.09
1400605834,13635682.11
1400606038,13788132.68
1400606140,13834040.49

1 1400242718 5649455.80
401 1400604504 13787120.46
402 1400604527 13505264.87
403 1400604546 13522321.17
404 1400605108 13746963.64
405 1400605113 13899221.05
406 1400605117 13066929.36
407 1400605122 13818325.58
408 1400605132 13624101.24
409 1400605227 12992570.34
410 1400605241 13631407.12
411 1400605247 13773296.72
412 1400605254 13601113.09
413 1400605334 13477173.69
414 1400605341 13528406.95
415 1400605371 13822120.38
416 1400605378 13627925.89
417 1400605452 13704460.37
418 1400605482 13612516.46
419 1400605625 12647482.46
420 1400605676 13671799.76
421 1400605706 13269956.01
422 1400605735 13684822.09
423 1400605834 13635682.11
424 1400606038 13788132.68
425 1400606140 13834040.49

View file

@ -66,35 +66,32 @@ START_TEST (test_compile)
r3_tree_insert_path(n, "/{id}", NULL); r3_tree_insert_path(n, "/{id}", NULL);
r3_tree_compile(n); r3_tree_compile(n);
r3_tree_compile(n); // test double compile r3_tree_compile(n); // test double compile
#ifdef DEBUG
r3_tree_dump(n, 0); r3_tree_dump(n, 0);
#endif
match_entry * entry; match_entry * entry;
entry = match_entry_createl( "foo" , strlen("/foo") ); entry = match_entry_createl( "foo" , strlen("/foo") );
m = r3_tree_matchl( n , "/foo", strlen("/foo"), entry); m = r3_tree_matchl( n , "/foo", strlen("/foo"), entry);
fail_if( NULL == m ); ck_assert( m );
entry = match_entry_createl( "/zoo" , strlen("/zoo") ); entry = match_entry_createl( "/zoo" , strlen("/zoo") );
m = r3_tree_matchl( n , "/zoo", strlen("/zoo"), entry); m = r3_tree_matchl( n , "/zoo", strlen("/zoo"), entry);
fail_if( NULL == m ); ck_assert( m );
entry = match_entry_createl( "/bar" , strlen("/bar") ); entry = match_entry_createl( "/bar" , strlen("/bar") );
m = r3_tree_matchl( n , "/bar", strlen("/bar"), entry); m = r3_tree_matchl( n , "/bar", strlen("/bar"), entry);
fail_if( NULL == m ); ck_assert( m );
entry = match_entry_createl( "/xxx" , strlen("/xxx") ); entry = match_entry_createl( "/xxx" , strlen("/xxx") );
m = r3_tree_matchl( n , "/xxx", strlen("/xxx"), entry); m = r3_tree_matchl( n , "/xxx", strlen("/xxx"), entry);
fail_if( NULL == m ); ck_assert( m );
entry = match_entry_createl( "/foo/xxx" , strlen("/foo/xxx") ); entry = match_entry_createl( "/foo/xxx" , strlen("/foo/xxx") );
m = r3_tree_matchl( n , "/foo/xxx", strlen("/foo/xxx"), entry); m = r3_tree_matchl( n , "/foo/xxx", strlen("/foo/xxx"), entry);
fail_if( NULL == m ); ck_assert( m );
entry = match_entry_createl( "/some_id" , strlen("/some_id") ); entry = match_entry_createl( "/some_id" , strlen("/some_id") );
m = r3_tree_matchl( n , "/some_id", strlen("/some_id"), entry); m = r3_tree_matchl( n , "/some_id", strlen("/some_id"), entry);
fail_if( NULL == m ); ck_assert( m );
ck_assert( m->endpoint > 0 ); // should not be an endpoint
} }
END_TEST END_TEST
@ -128,6 +125,9 @@ START_TEST (test_pcre_patterns_insert_2)
{ {
node * n = r3_tree_create(10); node * n = r3_tree_create(10);
r3_tree_insert_path(n, "/post/{idx:\\d{2}}/{idy:\\d{2}}", NULL); r3_tree_insert_path(n, "/post/{idx:\\d{2}}/{idy:\\d{2}}", NULL);
r3_tree_insert_path(n, "/zoo", NULL);
r3_tree_insert_path(n, "/foo", NULL);
r3_tree_insert_path(n, "/bar", NULL);
r3_tree_compile(n); r3_tree_compile(n);
r3_tree_dump(n, 0); r3_tree_dump(n, 0);
node *matched; node *matched;
@ -143,18 +143,35 @@ END_TEST
START_TEST (test_pcre_patterns_insert_3) START_TEST (test_pcre_patterns_insert_3)
{ {
node * n = r3_tree_create(10); node * n = r3_tree_create(10);
printf("Inserting /post/{idx:\\d{2}}/{idy}\n");
r3_tree_insert_path(n, "/post/{idx:\\d{2}}/{idy}", NULL); r3_tree_insert_path(n, "/post/{idx:\\d{2}}/{idy}", NULL);
r3_tree_dump(n, 0);
printf("Inserting /zoo\n");
r3_tree_insert_path(n, "/zoo", NULL);
r3_tree_dump(n, 0);
r3_tree_insert_path(n, "/foo", NULL);
r3_tree_insert_path(n, "/bar", NULL);
r3_tree_compile(n); r3_tree_compile(n);
r3_tree_dump(n, 0); r3_tree_dump(n, 0);
node *matched; node *matched;
matched = r3_tree_match(n, "/post/11/22", NULL);
ck_assert(matched);
matched = r3_tree_match(n, "/post/11", NULL); matched = r3_tree_match(n, "/post/11", NULL);
ck_assert(!matched); ck_assert(!matched);
matched = r3_tree_match(n, "/post/11/", NULL); matched = r3_tree_match(n, "/post/11/", NULL);
ck_assert(!matched); ck_assert(!matched);
/*
matched = r3_tree_match(n, "/post/113", NULL); matched = r3_tree_match(n, "/post/113", NULL);
ck_assert(!matched); ck_assert(!matched);
*/
} }
END_TEST END_TEST
@ -284,7 +301,7 @@ START_TEST(test_pcre_pattern_more)
r3_tree_insert_path(n, "/user3/{id:\\d{3}}", &var3); r3_tree_insert_path(n, "/user3/{id:\\d{3}}", &var3);
r3_tree_insert_path(n, "/user", &var0); r3_tree_insert_path(n, "/user", &var0);
r3_tree_compile(n); r3_tree_compile(n);
// r3_tree_dump(n, 0); r3_tree_dump(n, 0);
node *matched; node *matched;
matched = r3_tree_matchl(n, "/user/123", strlen("/user/123"), entry); matched = r3_tree_matchl(n, "/user/123", strlen("/user/123"), entry);