diff --git a/include/r3_define.h b/include/r3_define.h index bee91da..8658008 100644 --- a/include/r3_define.h +++ b/include/r3_define.h @@ -18,7 +18,7 @@ typedef unsigned char bool; # define TRUE 1 #endif -// #define DEBUG 1 +#define DEBUG 1 #ifdef DEBUG #define info(fmt, ...) \ diff --git a/include/r3_str.h b/include/r3_str.h index 6d821ad..c55dd38 100644 --- a/include/r3_str.h +++ b/include/r3_str.h @@ -20,6 +20,11 @@ char * compile_slug(char * str, int len); bool contains_slug(char * str); +char * find_slug_pattern(char *s1); + +char * find_slug_placeholder(char *s1, int *len); + +char * inside_slug(char * needle, int needle_len, char *offset); char * ltrim_slash(char* str); diff --git a/src/edge.c b/src/edge.c index 993fa2a..c9b621a 100644 --- a/src/edge.c +++ b/src/edge.c @@ -35,7 +35,11 @@ edge * r3_edge_create(char * pattern, int pattern_len, node * child) { /** - * branch the edge pattern at "dl" offset + * branch the edge pattern at "dl" offset, + * insert a dummy child between the edges. + * + * parent -> [edge1] -> childA + * parent -> [edge1] -> childB -> edge2 ->child A * */ void r3_edge_branch(edge *e, int dl) { @@ -61,12 +65,18 @@ void r3_edge_branch(edge *e, int dl) { e->child->edge_len = 0; e->child->endpoint--; - info("branched pattern: %s\n", e1->pattern); + // info("branched pattern: %s\n", e1->pattern); r3_node_append_edge(e->child, e1); c1->endpoint++; c1->data = e->child->data; // copy data pointer e->child->data = NULL; + + // truncate the original edge pattern + char *op = e->pattern; + e->pattern = strndup(e->pattern, dl); + e->pattern_len = dl; + free(op); } void r3_edge_free(edge * e) { diff --git a/src/node.c b/src/node.c index 5456ae3..7a36a1a 100644 --- a/src/node.c +++ b/src/node.c @@ -236,7 +236,7 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { // if the pcre_pattern is found, and the pointer is not NULL, then it's // 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); + // info("pcre matching %s on %s\n", n->combined_pattern, path); rc = pcre_exec( n->pcre_pattern, /* the compiled pattern */ @@ -250,7 +250,7 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { n->ov, /* output vector for substring information */ n->ov_cnt); /* number of elements in the output vector */ - info("rc: %d\n", rc ); + // info("rc: %d\n", rc ); if (rc < 0) { switch(rc) { @@ -268,11 +268,11 @@ node * r3_tree_match(node * n, char * path, int path_len, match_entry * entry) { { 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); + // info("%2d: %.*s\n", i, substring_length, substring_start); if ( substring_length > 0) { 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); + // info("matched item => restlen:%d edges:%d i:%d\n", restlen, n->edge_len, i); e = n->edges[i - 1]; @@ -323,7 +323,7 @@ inline edge * r3_node_find_edge_str(node * n, char * str, int str_len) { } } - // 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,matched_idx), str, node_edge_pattern_len(n,matched_idx) ) == 0 ) { return n->edges[matched_idx]; } @@ -392,46 +392,64 @@ node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, edge * e = NULL; /* length of common prefix */ - int offset = 0; + int prefix_len = 0; for( int i = 0 ; i < n->edge_len ; i++ ) { - offset = strndiff(path, n->edges[i]->pattern, n->edges[i]->pattern_len); + prefix_len = strndiff(path, n->edges[i]->pattern, n->edges[i]->pattern_len); - // printf("offset: %d %s vs %s\n", offset, path, n->edges[i]->pattern ); + // printf("prefix_len: %d %s vs %s\n", prefix_len, path, n->edges[i]->pattern ); // no common, consider insert a new edge - if ( offset > 0 ) { + if ( prefix_len > 0 ) { e = n->edges[i]; break; } } // branch the edge at correct position (avoid broken slugs) - char *slug_s = strchr(path, '{'); - char *slug_e = strchr(path, '}'); - if ( slug_s && slug_e ) { - if ( offset > (slug_s - path) && offset < (slug_e - path) ) { - // break before '{' - offset = slug_s - path; - } + char *slug_s; + if ( (slug_s = inside_slug(path, path_len, path + prefix_len)) != NULL ) { + prefix_len = slug_s - path; } - if ( offset == 0 ) { - // not found, we should just insert a whole new edge - node * child = r3_tree_create(3); - r3_node_add_child(n, strndup(path, path_len) , child); - info("edge not found, insert one: %s\n", path); - child->data = data; - child->endpoint++; + // common prefix not found, insert a new edge for this pattern + if ( prefix_len == 0 ) { + // there are two more slugs, we should break them into several parts + if ( count_slug(path, path_len) > 1 ) { + char *p = find_slug_placeholder(path, NULL); - if (route) { - route->data = data; - r3_node_append_route(child, route); +#ifdef DEBUG + assert(p); +#endif + + // find the next one + p = find_slug_placeholder(p + 1, NULL); +#ifdef DEBUG + assert(p); +#endif + + // 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); + + // and insert the rest part to the child + return r3_tree_insert_pathl(tree, p, path_len - (int)(p - path), route, data); + } else { + node * child = r3_tree_create(3); + r3_node_add_child(n, strndup(path, path_len) , child); + // info("edge not found, insert one: %s\n", path); + child->data = data; + child->endpoint++; + + if (route) { + route->data = data; + r3_node_append_route(child, route); + } + return child; } - return child; - } else if ( offset == e->pattern_len ) { // fully-equal to the pattern of the edge + } else if ( prefix_len == e->pattern_len ) { // fully-equal to the pattern of the edge - char * subpath = path + offset; - int subpath_len = path_len - offset; + char * subpath = path + prefix_len; + int subpath_len = path_len - prefix_len; // there are something more we can insert if ( subpath_len > 0 ) { @@ -447,8 +465,8 @@ node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, return e->child; } - } else if ( offset < e->pattern_len ) { - // printf("branch the edge offset: %d\n", offset); + } else if ( prefix_len < e->pattern_len ) { + // printf("branch the edge prefix_len: %d\n", prefix_len); /* it's partially matched with the pattern, @@ -456,25 +474,18 @@ node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, */ node *c2; // child 1, child 2 edge *e2; // edge 1, edge 2 - char * s2 = path + offset; + char * s2 = path + prefix_len; int s2_len = 0; - r3_edge_branch(e, offset); + r3_edge_branch(e, prefix_len); // here is the new edge from. c2 = r3_tree_create(3); - s2_len = path_len - offset; + s2_len = path_len - prefix_len; e2 = r3_edge_create(strndup(s2, s2_len), s2_len, c2); // printf("edge right: %s\n", e2->pattern); r3_node_append_edge(e->child, e2); - - char *op = e->pattern; - // truncate the original edge pattern - e->pattern = strndup(e->pattern, offset); - e->pattern_len = offset; - free(op); - // move n->edges to c1 c2->endpoint++; c2->data = data; diff --git a/src/str.c b/src/str.c index 35090c8..bf9ebb3 100644 --- a/src/str.c +++ b/src/str.c @@ -37,9 +37,16 @@ int strdiff(char * d1, char * d2) { */ int count_slug(char * p, int len) { int s = 0; + int lev = 0; while( len-- ) { - if ( *p == '{' ) + if ( lev == 0 && *p == '{' ) s++; + if ( *p == '{' ) { + lev++; + } + if ( *p == '}' ) { + lev--; + } p++; } return s; @@ -49,6 +56,89 @@ bool contains_slug(char * str) { return strchr(str, '{') != NULL ? TRUE : FALSE; } +char * inside_slug(char * needle, int needle_len, char *offset) { + char * s1 = offset; + char * s2 = offset; + + while( s1 >= needle ) { + if ( *s1 == '{' ) { + break; + } + s1--; + } + + char *end = needle+ needle_len; + while( s2 < end ) { + if ( *s2 == '}' ) { + break; + } + s2++; + } + + if ( *s1 == '{' && *s2 == '}' ) { + return s1; + } + return NULL; +} + +char * find_slug_placeholder(char *s1, int *len) { + char *c; + char *s2; + int cnt = 0; + if ( NULL != (c = strchr(s1, '{')) ) { + // find closing '}' + s2 = c; + while(*s2) { + if (*s2 == '{' ) + cnt++; + else if (*s2 == '}' ) + cnt--; + if (cnt == 0) + break; + s2++; + } + } else { + return NULL; + } + if (cnt!=0) { + return NULL; + } + if(len) { + *len = s2 - c + 1; + } + return c; +} + + +/** + * given a slug string, duplicate the pattern string of the slug + */ +char * find_slug_pattern(char *s1) { + char *c; + char *s2; + int cnt = 1; + if ( NULL != (c = strchr(s1, ':')) ) { + c++; + // find closing '}' + s2 = c; + while(s2) { + if (*s2 == '{' ) + cnt++; + else if (*s2 == '}' ) + cnt--; + if (cnt == 0) + break; + s2++; + } + + } else { + return NULL; + } + int len = s2 - c; + return strndup(c, len); +} + + /** * @param char * sep separator */ diff --git a/tests/Makefile.am b/tests/Makefile.am index fe81543..f49d01d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,6 +6,7 @@ # endif TESTS = check_tree AM_CFLAGS = $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ +AM_LDFLAGS = $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ noinst_HEADERS = \ bench.h \ @@ -18,17 +19,23 @@ dist_noinst_DATA = \ if ENABLE_GRAPHVIZ TESTS += check_gvc check_gvc_SOURCES = check_gvc.c bench.c -check_gvc_LDADD = $(GVC_DEPS_LIBS) $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ -check_gvc_CFLAGS = $(GVC_DEPS_CFLAGS) $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ +# check_gvc_LDADD = $(GVC_DEPS_LIBS) $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ +# check_gvc_CFLAGS = $(GVC_DEPS_CFLAGS) $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ AM_CFLAGS += $(GVC_DEPS_CFLAGS) +AM_LDFLAGS += $(GVC_DEPS_LIBS) endif # noinst_PROGRAMS = $(TESTS) check_tree_SOURCES = check_tree.c bench.c -check_tree_LDADD=$(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ -check_tree_CFLAGS=$(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ +# check_tree_LDADD=$(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ +# check_tree_CFLAGS=$(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ + +TESTS += check_slug +check_slug_SOURCES = check_slug.c + + check_PROGRAMS = $(TESTS) diff --git a/tests/Makefile.in b/tests/Makefile.in index dfeffda..befea66 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -79,9 +79,12 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -TESTS = check_tree$(EXEEXT) $(am__EXEEXT_1) +TESTS = check_tree$(EXEEXT) $(am__EXEEXT_1) check_slug$(EXEEXT) @ENABLE_GRAPHVIZ_TRUE@am__append_1 = check_gvc +# check_gvc_LDADD = $(GVC_DEPS_LIBS) $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ +# check_gvc_CFLAGS = $(GVC_DEPS_CFLAGS) $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ @ENABLE_GRAPHVIZ_TRUE@am__append_2 = $(GVC_DEPS_CFLAGS) +@ENABLE_GRAPHVIZ_TRUE@am__append_3 = $(GVC_DEPS_LIBS) check_PROGRAMS = $(am__EXEEXT_2) subdir = tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ @@ -99,29 +102,22 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @ENABLE_GRAPHVIZ_TRUE@am__EXEEXT_1 = check_gvc$(EXEEXT) -am__EXEEXT_2 = check_tree$(EXEEXT) $(am__EXEEXT_1) +am__EXEEXT_2 = check_tree$(EXEEXT) $(am__EXEEXT_1) check_slug$(EXEEXT) am__check_gvc_SOURCES_DIST = check_gvc.c bench.c -@ENABLE_GRAPHVIZ_TRUE@am_check_gvc_OBJECTS = \ -@ENABLE_GRAPHVIZ_TRUE@ check_gvc-check_gvc.$(OBJEXT) \ -@ENABLE_GRAPHVIZ_TRUE@ check_gvc-bench.$(OBJEXT) +@ENABLE_GRAPHVIZ_TRUE@am_check_gvc_OBJECTS = check_gvc.$(OBJEXT) \ +@ENABLE_GRAPHVIZ_TRUE@ bench.$(OBJEXT) check_gvc_OBJECTS = $(am_check_gvc_OBJECTS) -am__DEPENDENCIES_1 = -@ENABLE_GRAPHVIZ_TRUE@check_gvc_DEPENDENCIES = $(am__DEPENDENCIES_1) \ -@ENABLE_GRAPHVIZ_TRUE@ $(am__DEPENDENCIES_1) +check_gvc_LDADD = $(LDADD) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -check_gvc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(check_gvc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am_check_tree_OBJECTS = check_tree-check_tree.$(OBJEXT) \ - check_tree-bench.$(OBJEXT) +am_check_slug_OBJECTS = check_slug.$(OBJEXT) +check_slug_OBJECTS = $(am_check_slug_OBJECTS) +check_slug_LDADD = $(LDADD) +am_check_tree_OBJECTS = check_tree.$(OBJEXT) bench.$(OBJEXT) check_tree_OBJECTS = $(am_check_tree_OBJECTS) -check_tree_DEPENDENCIES = $(am__DEPENDENCIES_1) -check_tree_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(check_tree_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +check_tree_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -156,8 +152,10 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(check_gvc_SOURCES) $(check_tree_SOURCES) -DIST_SOURCES = $(am__check_gvc_SOURCES_DIST) $(check_tree_SOURCES) +SOURCES = $(check_gvc_SOURCES) $(check_slug_SOURCES) \ + $(check_tree_SOURCES) +DIST_SOURCES = $(am__check_gvc_SOURCES_DIST) $(check_slug_SOURCES) \ + $(check_tree_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -514,6 +512,8 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CFLAGS = $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include \ @CHECK_CFLAGS@ $(am__append_2) +AM_LDFLAGS = $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ \ + $(am__append_3) noinst_HEADERS = \ bench.h \ $(NULL) @@ -523,13 +523,10 @@ dist_noinst_DATA = \ $(NULL) @ENABLE_GRAPHVIZ_TRUE@check_gvc_SOURCES = check_gvc.c bench.c -@ENABLE_GRAPHVIZ_TRUE@check_gvc_LDADD = $(GVC_DEPS_LIBS) $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ -@ENABLE_GRAPHVIZ_TRUE@check_gvc_CFLAGS = $(GVC_DEPS_CFLAGS) $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ # noinst_PROGRAMS = $(TESTS) check_tree_SOURCES = check_tree.c bench.c -check_tree_LDADD = $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@ -check_tree_CFLAGS = $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@ +check_slug_SOURCES = check_slug.c # AM_CFLAGS=$(DEPS_CFLAGS) -I$(top_builddir)/include # AM_CFLAGS=$(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @@ -580,11 +577,15 @@ clean-checkPROGRAMS: check_gvc$(EXEEXT): $(check_gvc_OBJECTS) $(check_gvc_DEPENDENCIES) $(EXTRA_check_gvc_DEPENDENCIES) @rm -f check_gvc$(EXEEXT) - $(AM_V_CCLD)$(check_gvc_LINK) $(check_gvc_OBJECTS) $(check_gvc_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(check_gvc_OBJECTS) $(check_gvc_LDADD) $(LIBS) + +check_slug$(EXEEXT): $(check_slug_OBJECTS) $(check_slug_DEPENDENCIES) $(EXTRA_check_slug_DEPENDENCIES) + @rm -f check_slug$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(check_slug_OBJECTS) $(check_slug_LDADD) $(LIBS) check_tree$(EXEEXT): $(check_tree_OBJECTS) $(check_tree_DEPENDENCIES) $(EXTRA_check_tree_DEPENDENCIES) @rm -f check_tree$(EXEEXT) - $(AM_V_CCLD)$(check_tree_LINK) $(check_tree_OBJECTS) $(check_tree_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(check_tree_OBJECTS) $(check_tree_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -592,10 +593,10 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_gvc-bench.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_gvc-check_gvc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_tree-bench.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_tree-check_tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_gvc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_slug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check_tree.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -618,62 +619,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -check_gvc-check_gvc.o: check_gvc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -MT check_gvc-check_gvc.o -MD -MP -MF $(DEPDIR)/check_gvc-check_gvc.Tpo -c -o check_gvc-check_gvc.o `test -f 'check_gvc.c' || echo '$(srcdir)/'`check_gvc.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_gvc-check_gvc.Tpo $(DEPDIR)/check_gvc-check_gvc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check_gvc.c' object='check_gvc-check_gvc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -c -o check_gvc-check_gvc.o `test -f 'check_gvc.c' || echo '$(srcdir)/'`check_gvc.c - -check_gvc-check_gvc.obj: check_gvc.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -MT check_gvc-check_gvc.obj -MD -MP -MF $(DEPDIR)/check_gvc-check_gvc.Tpo -c -o check_gvc-check_gvc.obj `if test -f 'check_gvc.c'; then $(CYGPATH_W) 'check_gvc.c'; else $(CYGPATH_W) '$(srcdir)/check_gvc.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_gvc-check_gvc.Tpo $(DEPDIR)/check_gvc-check_gvc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check_gvc.c' object='check_gvc-check_gvc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -c -o check_gvc-check_gvc.obj `if test -f 'check_gvc.c'; then $(CYGPATH_W) 'check_gvc.c'; else $(CYGPATH_W) '$(srcdir)/check_gvc.c'; fi` - -check_gvc-bench.o: bench.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -MT check_gvc-bench.o -MD -MP -MF $(DEPDIR)/check_gvc-bench.Tpo -c -o check_gvc-bench.o `test -f 'bench.c' || echo '$(srcdir)/'`bench.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_gvc-bench.Tpo $(DEPDIR)/check_gvc-bench.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bench.c' object='check_gvc-bench.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -c -o check_gvc-bench.o `test -f 'bench.c' || echo '$(srcdir)/'`bench.c - -check_gvc-bench.obj: bench.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -MT check_gvc-bench.obj -MD -MP -MF $(DEPDIR)/check_gvc-bench.Tpo -c -o check_gvc-bench.obj `if test -f 'bench.c'; then $(CYGPATH_W) 'bench.c'; else $(CYGPATH_W) '$(srcdir)/bench.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_gvc-bench.Tpo $(DEPDIR)/check_gvc-bench.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bench.c' object='check_gvc-bench.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_gvc_CFLAGS) $(CFLAGS) -c -o check_gvc-bench.obj `if test -f 'bench.c'; then $(CYGPATH_W) 'bench.c'; else $(CYGPATH_W) '$(srcdir)/bench.c'; fi` - -check_tree-check_tree.o: check_tree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -MT check_tree-check_tree.o -MD -MP -MF $(DEPDIR)/check_tree-check_tree.Tpo -c -o check_tree-check_tree.o `test -f 'check_tree.c' || echo '$(srcdir)/'`check_tree.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_tree-check_tree.Tpo $(DEPDIR)/check_tree-check_tree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check_tree.c' object='check_tree-check_tree.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -c -o check_tree-check_tree.o `test -f 'check_tree.c' || echo '$(srcdir)/'`check_tree.c - -check_tree-check_tree.obj: check_tree.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -MT check_tree-check_tree.obj -MD -MP -MF $(DEPDIR)/check_tree-check_tree.Tpo -c -o check_tree-check_tree.obj `if test -f 'check_tree.c'; then $(CYGPATH_W) 'check_tree.c'; else $(CYGPATH_W) '$(srcdir)/check_tree.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_tree-check_tree.Tpo $(DEPDIR)/check_tree-check_tree.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='check_tree.c' object='check_tree-check_tree.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -c -o check_tree-check_tree.obj `if test -f 'check_tree.c'; then $(CYGPATH_W) 'check_tree.c'; else $(CYGPATH_W) '$(srcdir)/check_tree.c'; fi` - -check_tree-bench.o: bench.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -MT check_tree-bench.o -MD -MP -MF $(DEPDIR)/check_tree-bench.Tpo -c -o check_tree-bench.o `test -f 'bench.c' || echo '$(srcdir)/'`bench.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_tree-bench.Tpo $(DEPDIR)/check_tree-bench.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bench.c' object='check_tree-bench.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -c -o check_tree-bench.o `test -f 'bench.c' || echo '$(srcdir)/'`bench.c - -check_tree-bench.obj: bench.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -MT check_tree-bench.obj -MD -MP -MF $(DEPDIR)/check_tree-bench.Tpo -c -o check_tree-bench.obj `if test -f 'bench.c'; then $(CYGPATH_W) 'bench.c'; else $(CYGPATH_W) '$(srcdir)/bench.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/check_tree-bench.Tpo $(DEPDIR)/check_tree-bench.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bench.c' object='check_tree-bench.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_tree_CFLAGS) $(CFLAGS) -c -o check_tree-bench.obj `if test -f 'bench.c'; then $(CYGPATH_W) 'bench.c'; else $(CYGPATH_W) '$(srcdir)/bench.c'; fi` - mostlyclean-libtool: -rm -f *.lo @@ -887,6 +832,13 @@ check_gvc.log: check_gvc$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +check_slug.log: check_slug$(EXEEXT) + @p='check_slug$(EXEEXT)'; \ + b='check_slug'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ diff --git a/tests/bench_str.csv b/tests/bench_str.csv index e293f09..d86820a 100644 --- a/tests/bench_str.csv +++ b/tests/bench_str.csv @@ -186,3 +186,63 @@ 1400396725,10488850.71 1400396745,10442025.32 1400396765,10689592.72 +1400406039,11164926.18 +1400406130,10852846.69 +1400406200,9606388.04 +1400406388,10630125.97 +1400406712,10901099.14 +1400406757,10977776.63 +1400406780,10923630.07 +1400406834,10665256.26 +1400406846,10841057.59 +1400406860,10987088.01 +1400406868,10991821.64 +1400406881,11040200.72 +1400406887,11491514.59 +1400406950,10874497.93 +1400407239,11002642.12 +1400407250,10744268.90 +1400407276,11144966.17 +1400407292,10470853.00 +1400407305,10632588.97 +1400407323,11275701.84 +1400407364,10827173.25 +1400407380,11232917.51 +1400407384,10892217.62 +1400407454,10793665.50 +1400407490,11078867.15 +1400407498,10995093.02 +1400407520,10914505.42 +1400407544,10139300.12 +1400407549,11140837.53 +1400407572,11242381.65 +1400407586,10545015.96 +1400407832,11318167.86 +1400407846,11412502.78 +1400407864,10788301.74 +1400408080,10813960.08 +1400408117,11053281.53 +1400408148,10925976.71 +1400408157,10866706.90 +1400408486,10438246.84 +1400408495,10637030.99 +1400408503,10998237.54 +1400408743,10746673.10 +1400408973,10696597.06 +1400409590,10747379.89 +1400409621,10925100.16 +1400409674,10243836.44 +1400409691,10938038.79 +1400409739,10663533.54 +1400409845,11063203.93 +1400409863,11118679.72 +1400410121,10935751.60 +1400410132,10839286.96 +1400410167,10427826.47 +1400410180,10851581.27 +1400410252,11133237.55 +1400410283,10618062.83 +1400410318,10166831.58 +1400410399,11007341.02 +1400410441,10929677.98 +1400410704,10685427.91 diff --git a/tests/check_tree.c b/tests/check_tree.c index 07dc114..8355688 100644 --- a/tests/check_tree.c +++ b/tests/check_tree.c @@ -4,6 +4,7 @@ #include #include "r3.h" #include "r3_str.h" +#include "r3_define.h" #include "str_array.h" #include "bench.h" @@ -160,31 +161,40 @@ START_TEST (test_compile_slug) END_TEST +START_TEST (test_r3_tree_pcre_patterns_insert) +{ + node * n = r3_tree_create(10); + + // r3_tree_insert_path(n, "/foo-{user}-{id}", NULL, NULL); + // r3_tree_dump(n, 0); + r3_tree_insert_pathl(n, "/post/{handle}-{id}", strlen("/post/{handle}-{id}"), NULL, NULL); + r3_tree_compile(n); + r3_tree_dump(n, 0); + r3_tree_free(n); +} +END_TEST + + + + START_TEST (test_r3_tree_insert_pathl) { node * n = r3_tree_create(10); - info("Inserting /foo/bar\n"); r3_tree_insert_path(n, "/foo/bar", NULL, NULL); // r3_tree_dump(n, 0); - info("Inserting /foo/zoo\n"); r3_tree_insert_path(n, "/foo/zoo", NULL, NULL); // r3_tree_dump(n, 0); - info("Inserting /f/id\n"); r3_tree_insert_path(n, "/f/id" , NULL, NULL); // r3_tree_dump(n, 0); - info("Inserting /post/{id}\n"); r3_tree_insert_pathl(n, "/post/{id}", strlen("/post/{id}"), NULL, NULL); // r3_tree_dump(n, 0); - info("Inserting /post/{handle}\n"); r3_tree_insert_pathl(n, "/post/{handle}", strlen("/post/{handle}"), NULL, NULL); - // r3_tree_dump(n, 0); - info("Inserting /post/{handle}-{id}\n"); r3_tree_insert_pathl(n, "/post/{handle}-{id}", strlen("/post/{handle}-{id}"), NULL, NULL); r3_tree_compile(n); @@ -255,7 +265,7 @@ START_TEST(test_pcre_pattern_simple) r3_tree_insert_pathl(n, "/user/{id:\\d+}", strlen("/user/{id:\\d+}"), NULL, NULL); r3_tree_insert_pathl(n, "/user", strlen("/user"), NULL, NULL); r3_tree_compile(n); - r3_tree_dump(n, 0); + // r3_tree_dump(n, 0); node *matched; matched = r3_tree_match(n, "/user/123", strlen("/user/123"), entry); fail_if(matched == NULL); @@ -286,7 +296,7 @@ START_TEST(test_pcre_pattern_more) r3_tree_insert_pathl(n, "/user3/{id:\\d{3}}", strlen("/user3/{id:\\d{3}}"), NULL, &var3); r3_tree_insert_pathl(n, "/user", strlen("/user"), NULL, &var0); r3_tree_compile(n); - r3_tree_dump(n, 0); + // r3_tree_dump(n, 0); node *matched; matched = r3_tree_match(n, "/user/123", strlen("/user/123"), entry); @@ -735,6 +745,7 @@ Suite* r3_suite (void) { tcase_add_test(tcase, test_insert_route); tcase_add_test(tcase, test_pcre_pattern_simple); tcase_add_test(tcase, test_pcre_pattern_more); + tcase_add_test(tcase, test_r3_tree_pcre_patterns_insert); tcase_add_test(tcase, benchmark_str);