From e9797295b5a8de0fa2989aa934f4379f9ad9be75 Mon Sep 17 00:00:00 2001 From: c9s Date: Wed, 21 May 2014 01:15:54 +0800 Subject: [PATCH] Fix endpoint when branching edges --- src/edge.c | 7 ++----- src/node.c | 13 +++++++------ tests/bench_str.csv | 22 ++++++++++++++++++++++ tests/check_tree.c | 37 +++++++++++++++++++++++++++---------- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/edge.c b/src/edge.c index 34e11f4..ae3c4c8 100644 --- a/src/edge.c +++ b/src/edge.c @@ -55,7 +55,6 @@ node * r3_edge_branch(edge *e, int dl) { new_child = r3_tree_create(3); s1_len = e->pattern_len - dl; 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. 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->edge_len = 0; - e->child->endpoint--; - - // info("branched pattern: %s\n", e1->pattern); + new_child->endpoint = e->child->endpoint; + e->child->endpoint = 0; // reset endpoint r3_node_append_edge(e->child, e1); - new_child->endpoint++; new_child->data = e->child->data; // copy data pointer e->child->data = NULL; diff --git a/src/node.c b/src/node.c index 27da599..000df5f 100644 --- a/src/node.c +++ b/src/node.c @@ -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)); } 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 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 ) { int restlen = path_len - e->pattern_len; 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); } @@ -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" node * child = r3_tree_create(3); r3_node_add_child(n, strndup(path, (int)(p - path)), child); + child->endpoint = 0; // and insert the rest part to the child 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 // see if there is an endpoint already - if (e->child->endpoint) { + if (e->child->endpoint > 0) { // XXX: return an error code instead of 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 ) { - // printf("branch the edge prefix_len: %d\n", prefix_len); - - /* it's partially matched with the pattern, * 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) { print_indent(level); + + printf("(o)"); + if ( n->combined_pattern ) { printf(" regexp:%s", n->combined_pattern); } diff --git a/tests/bench_str.csv b/tests/bench_str.csv index 735b297..c565e8c 100644 --- a/tests/bench_str.csv +++ b/tests/bench_str.csv @@ -401,3 +401,25 @@ 1400604504,13787120.46 1400604527,13505264.87 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 diff --git a/tests/check_tree.c b/tests/check_tree.c index 7f50dcc..cd5306c 100644 --- a/tests/check_tree.c +++ b/tests/check_tree.c @@ -66,35 +66,32 @@ START_TEST (test_compile) r3_tree_insert_path(n, "/{id}", NULL); r3_tree_compile(n); r3_tree_compile(n); // test double compile -#ifdef DEBUG r3_tree_dump(n, 0); -#endif match_entry * entry; entry = match_entry_createl( "foo" , strlen("/foo") ); m = r3_tree_matchl( n , "/foo", strlen("/foo"), entry); - fail_if( NULL == m ); + ck_assert( m ); entry = match_entry_createl( "/zoo" , strlen("/zoo") ); m = r3_tree_matchl( n , "/zoo", strlen("/zoo"), entry); - fail_if( NULL == m ); + ck_assert( m ); entry = match_entry_createl( "/bar" , strlen("/bar") ); m = r3_tree_matchl( n , "/bar", strlen("/bar"), entry); - fail_if( NULL == m ); + ck_assert( m ); entry = match_entry_createl( "/xxx" , strlen("/xxx") ); 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") ); 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") ); m = r3_tree_matchl( n , "/some_id", strlen("/some_id"), entry); - fail_if( NULL == m ); - ck_assert( m->endpoint > 0 ); // should not be an endpoint + ck_assert( m ); } END_TEST @@ -128,6 +125,9 @@ START_TEST (test_pcre_patterns_insert_2) { node * n = r3_tree_create(10); 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_dump(n, 0); node *matched; @@ -143,18 +143,35 @@ END_TEST START_TEST (test_pcre_patterns_insert_3) { 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_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_dump(n, 0); node *matched; + + + matched = r3_tree_match(n, "/post/11/22", NULL); + ck_assert(matched); + matched = r3_tree_match(n, "/post/11", NULL); ck_assert(!matched); + matched = r3_tree_match(n, "/post/11/", NULL); ck_assert(!matched); + /* matched = r3_tree_match(n, "/post/113", NULL); ck_assert(!matched); + */ } 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, "/user", &var0); r3_tree_compile(n); - // r3_tree_dump(n, 0); + r3_tree_dump(n, 0); node *matched; matched = r3_tree_matchl(n, "/user/123", strlen("/user/123"), entry);