Add benchmark and bug fixes
This commit is contained in:
parent
6b39b72ebe
commit
046ec9e977
6 changed files with 550 additions and 131 deletions
|
@ -12,8 +12,7 @@ typedef unsigned char bool;
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
|
|
||||||
|
// #define DEBUG 1
|
||||||
#define DEBUG 1
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
#define info(fmt, ...) \
|
#define info(fmt, ...) \
|
||||||
|
|
|
@ -21,7 +21,6 @@ struct _node;
|
||||||
typedef struct _edge edge;
|
typedef struct _edge edge;
|
||||||
typedef struct _node node;
|
typedef struct _node node;
|
||||||
|
|
||||||
|
|
||||||
struct _node {
|
struct _node {
|
||||||
edge ** edges;
|
edge ** edges;
|
||||||
int edge_len;
|
int edge_len;
|
||||||
|
@ -33,7 +32,6 @@ struct _node {
|
||||||
pcre * pcre_pattern;
|
pcre * pcre_pattern;
|
||||||
pcre_extra * pcre_extra;
|
pcre_extra * pcre_extra;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the pointer of route structure
|
* the pointer of route structure
|
||||||
*/
|
*/
|
||||||
|
@ -49,6 +47,12 @@ struct _edge {
|
||||||
node * child;
|
node * child;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char ** vars;
|
||||||
|
int vars_len;
|
||||||
|
char * path; // dispatched path
|
||||||
|
void * route_ptr; // route ptr
|
||||||
|
} match_entry;
|
||||||
|
|
||||||
|
|
||||||
node * rtree_create(int cap);
|
node * rtree_create(int cap);
|
||||||
|
@ -65,8 +69,6 @@ edge * node_find_edge(node * n, char * pat);
|
||||||
|
|
||||||
void rtree_append_edge(node *n, edge *child);
|
void rtree_append_edge(node *n, edge *child);
|
||||||
|
|
||||||
node * rtree_insert_tokens(node * tree, token_array * tokens);
|
|
||||||
|
|
||||||
node * rtree_insert_path(node *tree, char *route, void * route_ptr);
|
node * rtree_insert_path(node *tree, char *route, void * route_ptr);
|
||||||
|
|
||||||
node * rtree_insert_pathn(node *tree, char *route, int route_len, void * route_ptr);
|
node * rtree_insert_pathn(node *tree, char *route, int route_len, void * route_ptr);
|
||||||
|
@ -80,7 +82,7 @@ void rtree_compile(node *n);
|
||||||
|
|
||||||
void rtree_compile_patterns(node * n);
|
void rtree_compile_patterns(node * n);
|
||||||
|
|
||||||
node * rtree_match(node * n, char * path, int path_len);
|
node * rtree_match(node * n, char * path, int path_len, match_entry * entry);
|
||||||
|
|
||||||
bool node_has_slug_edges(node *n);
|
bool node_has_slug_edges(node *n);
|
||||||
|
|
||||||
|
@ -92,4 +94,7 @@ void edge_branch(edge *e, int dl);
|
||||||
|
|
||||||
void edge_free(edge * edge);
|
void edge_free(edge * edge);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !NODE_H */
|
#endif /* !NODE_H */
|
||||||
|
|
|
@ -10,29 +10,29 @@
|
||||||
|
|
||||||
#include "define.h"
|
#include "define.h"
|
||||||
|
|
||||||
typedef struct _token_array {
|
typedef struct _str_array {
|
||||||
char **tokens;
|
char **tokens;
|
||||||
int len;
|
int len;
|
||||||
int cap;
|
int cap;
|
||||||
} token_array;
|
} str_array;
|
||||||
|
|
||||||
token_array * token_array_create(int cap);
|
str_array * str_array_create(int cap);
|
||||||
|
|
||||||
|
|
||||||
bool token_array_is_full(token_array * l);
|
bool str_array_is_full(str_array * l);
|
||||||
|
|
||||||
bool token_array_resize(token_array *l, int new_cap);
|
bool str_array_resize(str_array *l, int new_cap);
|
||||||
|
|
||||||
bool token_array_append(token_array * list, char * token);
|
bool str_array_append(str_array * list, char * token);
|
||||||
|
|
||||||
void token_array_free(token_array *l);
|
void str_array_free(str_array *l);
|
||||||
|
|
||||||
void token_array_dump(token_array *l);
|
void str_array_dump(str_array *l);
|
||||||
|
|
||||||
token_array * split_route_pattern(char *pattern, int pattern_len);
|
str_array * split_route_pattern(char *pattern, int pattern_len);
|
||||||
|
|
||||||
#define token_array_fetch(t,i) t->tokens[i]
|
#define str_array_fetch(t,i) t->tokens[i]
|
||||||
#define token_array_len(t) t->len
|
#define str_array_len(t) t->len
|
||||||
#define token_array_cap(t) t->cap
|
#define str_array_cap(t) t->cap
|
||||||
|
|
||||||
#endif /* !TOKEN_H */
|
#endif /* !TOKEN_H */
|
||||||
|
|
99
src/node.c
99
src/node.c
|
@ -45,7 +45,7 @@ void rtree_free(node * tree) {
|
||||||
free(tree->combined_pattern);
|
free(tree->combined_pattern);
|
||||||
|
|
||||||
free(tree->edges);
|
free(tree->edges);
|
||||||
// token_array_free(tree->edge_patterns);
|
// str_array_free(tree->edge_patterns);
|
||||||
free(tree);
|
free(tree);
|
||||||
tree = NULL;
|
tree = NULL;
|
||||||
}
|
}
|
||||||
|
@ -65,8 +65,8 @@ edge * rtree_add_child(node * n, char * pat , node *child) {
|
||||||
|
|
||||||
e = edge_create( pat, strlen(pat), child);
|
e = edge_create( pat, strlen(pat), child);
|
||||||
rtree_append_edge(n, e);
|
rtree_append_edge(n, e);
|
||||||
// token_array_append(n->edge_patterns, pat);
|
// str_array_append(n->edge_patterns, pat);
|
||||||
// assert( token_array_len(n->edge_patterns) == n->edge_len );
|
// assert( str_array_len(n->edge_patterns) == n->edge_len );
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,7 @@ void rtree_compile_patterns(node * n) {
|
||||||
|
|
||||||
p = cpat;
|
p = cpat;
|
||||||
|
|
||||||
|
|
||||||
edge *e = NULL;
|
edge *e = NULL;
|
||||||
for ( int i = 0 ; i < n->edge_len ; i++ ) {
|
for ( int i = 0 ; i < n->edge_len ; i++ ) {
|
||||||
e = n->edges[i];
|
e = n->edges[i];
|
||||||
|
@ -152,6 +153,12 @@ void rtree_compile_patterns(node * n) {
|
||||||
|
|
||||||
const char *error;
|
const char *error;
|
||||||
int erroffset;
|
int erroffset;
|
||||||
|
unsigned int option_bits;
|
||||||
|
|
||||||
|
if (n->pcre_pattern)
|
||||||
|
free(n->pcre_pattern);
|
||||||
|
if (n->pcre_extra)
|
||||||
|
free(n->pcre_extra);
|
||||||
|
|
||||||
// n->pcre_pattern;
|
// n->pcre_pattern;
|
||||||
n->pcre_pattern = pcre_compile(
|
n->pcre_pattern = pcre_compile(
|
||||||
|
@ -174,7 +181,9 @@ void rtree_compile_patterns(node * n) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
node * rtree_match(node * n, char * path, int path_len) {
|
node * rtree_match(node * n, char * path, int path_len, match_entry * entry) {
|
||||||
|
// info("try matching: %s\n", path);
|
||||||
|
|
||||||
if (n->combined_pattern && n->pcre_pattern) {
|
if (n->combined_pattern && 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_count = (n->edge_len + 1) * 2;
|
// int ovector_count = (n->edge_len + 1) * 2;
|
||||||
|
@ -206,18 +215,27 @@ node * rtree_match(node * n, char * path, int path_len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
edge *e;
|
||||||
for (i = 1; i < rc; i++)
|
for (i = 1; i < rc; i++)
|
||||||
{
|
{
|
||||||
char *substring_start = path + ovector[2*i];
|
char *substring_start = path + ovector[2*i];
|
||||||
int substring_length = ovector[2*i+1] - ovector[2*i];
|
int substring_length = ovector[2*i+1] - ovector[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 - ovector[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);
|
||||||
if (restlen) {
|
|
||||||
return rtree_match( n->edges[i - 1]->child, substring_start + substring_length, restlen);
|
e = n->edges[i - 1];
|
||||||
|
|
||||||
|
if (entry && e->has_slug) {
|
||||||
|
// entry->
|
||||||
}
|
}
|
||||||
return n->edges[i - 1]->child;
|
|
||||||
|
if (restlen == 0) {
|
||||||
|
return e->child;
|
||||||
|
}
|
||||||
|
return rtree_match( e->child, substring_start + substring_length, restlen, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// does not match
|
// does not match
|
||||||
|
@ -230,7 +248,7 @@ node * rtree_match(node * n, char * path, int path_len) {
|
||||||
if(len == 0) {
|
if(len == 0) {
|
||||||
return e->child;
|
return e->child;
|
||||||
} else {
|
} else {
|
||||||
return rtree_match(e->child, path + e->pattern_len, len);
|
return rtree_match(e->child, path + e->pattern_len, len, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -238,27 +256,43 @@ node * rtree_match(node * n, char * path, int path_len) {
|
||||||
|
|
||||||
edge * node_find_edge_str(node * n, char * str, int str_len) {
|
edge * node_find_edge_str(node * n, char * str, int str_len) {
|
||||||
edge *e;
|
edge *e;
|
||||||
|
char *p;
|
||||||
|
char *s;
|
||||||
for ( int i = 0 ; i < n->edge_len ; i++ ) {
|
for ( int i = 0 ; i < n->edge_len ; i++ ) {
|
||||||
e = n->edges[i];
|
e = n->edges[i];
|
||||||
char *p = e->pattern;
|
p = e->pattern;
|
||||||
while ( *p == *str ) {
|
s = str;
|
||||||
p++;
|
|
||||||
|
info("matching '%s' with '%s'\n", str, e->pattern);
|
||||||
|
if ( str_len < e->pattern_len ) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
if ( strncmp(e->pattern, str, e->pattern_len) == 0 ) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
while ( *p == *s ) {
|
||||||
|
p++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
info("matched len: %d == pattern len %d\n", (int)(p - e->pattern) , e->pattern_len);
|
||||||
if ( p - e->pattern == e->pattern_len ) {
|
if ( p - e->pattern == e->pattern_len ) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
node * rtree_lookup(node * tree, char * path, int path_len) {
|
node * rtree_lookup(node * tree, char * path, int path_len) {
|
||||||
token_array * tokens = split_route_pattern(path, path_len);
|
str_array * tokens = split_route_pattern(path, path_len);
|
||||||
|
|
||||||
node * n = tree;
|
node * n = tree;
|
||||||
edge * e = NULL;
|
edge * e = NULL;
|
||||||
for ( int i = 0 ; i < tokens->len ; i++ ) {
|
for ( int i = 0 ; i < tokens->len ; i++ ) {
|
||||||
e = node_find_edge(n, token_array_fetch(tokens, i) );
|
e = node_find_edge(n, str_array_fetch(tokens, i) );
|
||||||
if (!e) {
|
if (!e) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -282,25 +316,6 @@ node * node_create() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
node * rtree_insert_tokens(node * tree, token_array * tokens) {
|
|
||||||
node * n = tree;
|
|
||||||
edge * e = NULL;
|
|
||||||
for ( int i = 0 ; i < tokens->len ; i++ ) {
|
|
||||||
e = node_find_edge(n, token_array_fetch(tokens, i) );
|
|
||||||
if (e) {
|
|
||||||
n = e->child;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// insert node
|
|
||||||
node * child = node_create();
|
|
||||||
rtree_add_child(n, strdup(token_array_fetch(tokens,i)) , child);
|
|
||||||
n = child;
|
|
||||||
}
|
|
||||||
n->endpoint++;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
node * rtree_insert_path(node *tree, char *route, void * route_ptr)
|
node * rtree_insert_path(node *tree, char *route, void * route_ptr)
|
||||||
{
|
{
|
||||||
return rtree_insert_pathn(tree, route, strlen(route) , route_ptr);
|
return rtree_insert_pathn(tree, route, strlen(route) , route_ptr);
|
||||||
|
@ -343,6 +358,7 @@ node * rtree_insert_pathn(node *tree, char *route, int route_len, void * route_p
|
||||||
rtree_add_child(n, strndup(route, route_len) , child);
|
rtree_add_child(n, strndup(route, route_len) , child);
|
||||||
info("edge not found, insert one: %s\n", route);
|
info("edge not found, insert one: %s\n", route);
|
||||||
child->route_ptr = route_ptr;
|
child->route_ptr = route_ptr;
|
||||||
|
child->endpoint++;
|
||||||
return child;
|
return child;
|
||||||
} else if ( dl == e->pattern_len ) { // fully-equal to the pattern of the edge
|
} else if ( dl == e->pattern_len ) { // fully-equal to the pattern of the edge
|
||||||
|
|
||||||
|
@ -389,15 +405,10 @@ node * rtree_insert_pathn(node *tree, char *route, int route_len, void * route_p
|
||||||
c2->endpoint++;
|
c2->endpoint++;
|
||||||
c2->route_ptr = route_ptr;
|
c2->route_ptr = route_ptr;
|
||||||
return c2;
|
return c2;
|
||||||
} else if ( dl > 0 ) {
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
printf("unexpected condition.");
|
printf("unexpected condition.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// token_array * t = split_route_pattern(route, strlen(route));
|
|
||||||
// return rtree_insert_tokens(tree, t);
|
|
||||||
// n->endpoint++;
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +452,7 @@ void edge_branch(edge *e, int dl) {
|
||||||
e->child->edge_len = 0;
|
e->child->edge_len = 0;
|
||||||
e->child->endpoint--;
|
e->child->endpoint--;
|
||||||
|
|
||||||
info("branched pattern: %s", e1->pattern);
|
info("branched pattern: %s\n", e1->pattern);
|
||||||
|
|
||||||
rtree_append_edge(e->child, e1);
|
rtree_append_edge(e->child, e1);
|
||||||
c1->endpoint++;
|
c1->endpoint++;
|
||||||
|
@ -471,9 +482,11 @@ void edge_free(edge * e) {
|
||||||
void rtree_dump(node * n, int level) {
|
void rtree_dump(node * n, int level) {
|
||||||
if ( n->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("\n");
|
|
||||||
|
printf(" endpoint:%d\n", n->endpoint);
|
||||||
|
|
||||||
for ( int i = 0 ; i < n->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);
|
||||||
|
@ -491,3 +504,9 @@ void rtree_dump(node * n, int level) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
char * node_trace(node * n) {
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
30
src/token.c
30
src/token.c
|
@ -11,15 +11,15 @@
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
|
||||||
token_array * token_array_create(int cap) {
|
str_array * str_array_create(int cap) {
|
||||||
token_array * list = (token_array*) malloc( sizeof(token_array) );
|
str_array * list = (str_array*) malloc( sizeof(str_array) );
|
||||||
list->len = 0;
|
list->len = 0;
|
||||||
list->cap = cap;
|
list->cap = cap;
|
||||||
list->tokens = (char**) malloc( sizeof(char*) * cap);
|
list->tokens = (char**) malloc( sizeof(char*) * cap);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void token_array_free(token_array *l) {
|
void str_array_free(str_array *l) {
|
||||||
for ( int i = 0; i < l->len ; i++ ) {
|
for ( int i = 0; i < l->len ; i++ ) {
|
||||||
char * t = l->tokens[ i ];
|
char * t = l->tokens[ i ];
|
||||||
free(t);
|
free(t);
|
||||||
|
@ -27,19 +27,19 @@ void token_array_free(token_array *l) {
|
||||||
free(l);
|
free(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool token_array_is_full(token_array * l) {
|
bool str_array_is_full(str_array * l) {
|
||||||
return l->len >= l->cap;
|
return l->len >= l->cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool token_array_resize(token_array *l, int new_cap) {
|
bool str_array_resize(str_array *l, int new_cap) {
|
||||||
l->tokens = realloc(l->tokens, sizeof(char**) * new_cap);
|
l->tokens = realloc(l->tokens, sizeof(char**) * new_cap);
|
||||||
l->cap = new_cap;
|
l->cap = new_cap;
|
||||||
return l->tokens != NULL;
|
return l->tokens != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool token_array_append(token_array * l, char * token) {
|
bool str_array_append(str_array * l, char * token) {
|
||||||
if ( token_array_is_full(l) ) {
|
if ( str_array_is_full(l) ) {
|
||||||
bool ret = token_array_resize(l, l->cap + 20);
|
bool ret = str_array_resize(l, l->cap + 20);
|
||||||
if (ret == FALSE ) {
|
if (ret == FALSE ) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ bool token_array_append(token_array * l, char * token) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void token_array_dump(token_array *l) {
|
void str_array_dump(str_array *l) {
|
||||||
printf("[");
|
printf("[");
|
||||||
for ( int i = 0; i < l->len ; i++ ) {
|
for ( int i = 0; i < l->len ; i++ ) {
|
||||||
printf("\"%s\"", l->tokens[i] );
|
printf("\"%s\"", l->tokens[i] );
|
||||||
|
@ -79,10 +79,10 @@ void token_array_dump(token_array *l) {
|
||||||
*
|
*
|
||||||
* @return char**
|
* @return char**
|
||||||
*/
|
*/
|
||||||
token_array * split_route_pattern(char *pattern, int pattern_len) {
|
str_array * split_route_pattern(char *pattern, int pattern_len) {
|
||||||
char *s1, *p = pattern;
|
char *s1, *p = pattern;
|
||||||
|
|
||||||
token_array * token_array = token_array_create( 20 );
|
str_array * str_array = str_array_create( 20 );
|
||||||
|
|
||||||
s1 = p;
|
s1 = p;
|
||||||
p++;
|
p++;
|
||||||
|
@ -97,20 +97,20 @@ token_array * split_route_pattern(char *pattern, int pattern_len) {
|
||||||
}
|
}
|
||||||
p++; // contains the '}'
|
p++; // contains the '}'
|
||||||
// printf("==> %s\n", strndup(s1, p-s1) );
|
// printf("==> %s\n", strndup(s1, p-s1) );
|
||||||
token_array_append(token_array, strndup(s1, p-s1) );
|
str_array_append(str_array, strndup(s1, p-s1) );
|
||||||
s1 = p;
|
s1 = p;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ( *p == '/' ) {
|
else if ( *p == '/' ) {
|
||||||
// printf("==> %s\n", strndup(s1, p-s1) );
|
// printf("==> %s\n", strndup(s1, p-s1) );
|
||||||
token_array_append(token_array, strndup(s1, p-s1) );
|
str_array_append(str_array, strndup(s1, p-s1) );
|
||||||
s1 = p;
|
s1 = p;
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( p-s1 > 0 ) {
|
if ( p-s1 > 0 ) {
|
||||||
token_array_append(token_array, strndup(s1, p-s1) );
|
str_array_append(str_array, strndup(s1, p-s1) );
|
||||||
}
|
}
|
||||||
return token_array;
|
return str_array;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,32 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <check.h>
|
#include <check.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define MICRO_IN_SEC 1000000.00
|
||||||
|
#define SEC_IN_MIN 60
|
||||||
|
#define NUL '\0'
|
||||||
|
double microtime() {
|
||||||
|
struct timeval tp;
|
||||||
|
long sec = 0L;
|
||||||
|
double msec = 0.0;
|
||||||
|
char ret[100];
|
||||||
|
|
||||||
|
if (gettimeofday((struct timeval *) &tp, (NUL)) == 0) {
|
||||||
|
msec = (double) (tp.tv_usec / MICRO_IN_SEC);
|
||||||
|
sec = tp.tv_sec;
|
||||||
|
if (msec >= 1.0)
|
||||||
|
msec -= (long) msec;
|
||||||
|
return sec + msec;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
START_TEST (test_ltrim_slash)
|
START_TEST (test_ltrim_slash)
|
||||||
{
|
{
|
||||||
fail_if( strcmp( ltrim_slash("/blog") , "blog" ) != 0 );
|
fail_if( strcmp( ltrim_slash("/blog") , "blog" ) != 0 );
|
||||||
|
@ -42,11 +65,14 @@ END_TEST
|
||||||
|
|
||||||
START_TEST (test_compile)
|
START_TEST (test_compile)
|
||||||
{
|
{
|
||||||
token_array *t;
|
str_array *t;
|
||||||
node * n;
|
node * n;
|
||||||
n = rtree_create(10);
|
n = rtree_create(10);
|
||||||
|
|
||||||
|
|
||||||
|
match_entry * entry;
|
||||||
|
node *m;
|
||||||
|
edge *e ;
|
||||||
|
|
||||||
rtree_insert_pathn(n, "/zoo", strlen("/zoo"), NULL);
|
rtree_insert_pathn(n, "/zoo", strlen("/zoo"), NULL);
|
||||||
rtree_insert_pathn(n, "/foo", strlen("/foo"), NULL);
|
rtree_insert_pathn(n, "/foo", strlen("/foo"), NULL);
|
||||||
|
@ -55,43 +81,51 @@ START_TEST (test_compile)
|
||||||
fail_if( n->combined_pattern );
|
fail_if( n->combined_pattern );
|
||||||
fail_if( NULL == node_find_edge_str(n, "/", strlen("/") ) );
|
fail_if( NULL == node_find_edge_str(n, "/", strlen("/") ) );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
rtree_dump(n, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
rtree_insert_pathn(n, "/foo/{id}", strlen("/foo/{id}"), NULL);
|
rtree_insert_pathn(n, "/foo/{id}", strlen("/foo/{id}"), NULL);
|
||||||
rtree_insert_pathn(n, "/{id}", strlen("/{id}"), NULL);
|
rtree_insert_pathn(n, "/{id}", strlen("/{id}"), NULL);
|
||||||
rtree_compile(n);
|
rtree_compile(n);
|
||||||
|
rtree_compile(n); // test double compile
|
||||||
|
#ifdef DEBUG
|
||||||
rtree_dump(n, 0);
|
rtree_dump(n, 0);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
fail_if(n->edges[0]->child->combined_pattern == NULL);
|
fail_if(n->edges[0]->child->combined_pattern == NULL);
|
||||||
|
|
||||||
edge *e = node_find_edge_str(n, "/", strlen("/") );
|
e = node_find_edge_str(n, "/", strlen("/") );
|
||||||
fail_if( NULL == e );
|
fail_if( NULL == e );
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
printf( "%s\n", e->pattern );
|
printf( "%s\n", e->pattern );
|
||||||
printf( "%s\n", e->child->combined_pattern );
|
printf( "%s\n", e->child->combined_pattern );
|
||||||
printf( "%s\n", n->edges[0]->child->combined_pattern);
|
printf( "%s\n", n->edges[0]->child->combined_pattern);
|
||||||
printf( "%s\n", n->combined_pattern );
|
printf( "%s\n", n->combined_pattern );
|
||||||
*/
|
*/
|
||||||
node *m = rtree_match( e->child , "foo", strlen("foo") );
|
|
||||||
|
entry = calloc( sizeof(entry) , 1 );
|
||||||
|
|
||||||
|
|
||||||
|
m = rtree_match( n , "/foo", strlen("/foo"), entry);
|
||||||
fail_if( NULL == m );
|
fail_if( NULL == m );
|
||||||
|
|
||||||
m = rtree_match( n , "/foo", strlen("/foo") );
|
m = rtree_match( n , "/zoo", strlen("/zoo"), entry);
|
||||||
fail_if( NULL == m );
|
fail_if( NULL == m );
|
||||||
|
|
||||||
m = rtree_match( n , "/zoo", strlen("/zoo") );
|
m = rtree_match( n , "/bar", strlen("/bar"), entry);
|
||||||
fail_if( NULL == m );
|
fail_if( NULL == m );
|
||||||
|
|
||||||
m = rtree_match( n , "/bar", strlen("/bar") );
|
m = rtree_match( n , "/xxx", strlen("/xxx"), entry);
|
||||||
fail_if( NULL == m );
|
fail_if( NULL == m );
|
||||||
|
|
||||||
m = rtree_match( n , "/xxx", strlen("/xxx") );
|
m = rtree_match( n , "/foo/xxx", strlen("/foo/xxx"), entry);
|
||||||
fail_if( NULL == m );
|
fail_if( NULL == m );
|
||||||
|
|
||||||
m = rtree_match( n , "/foo/xxx", strlen("/foo/xxx") );
|
m = rtree_match( n , "/some_id", strlen("/some_id"), entry);
|
||||||
fail_if( NULL == m );
|
fail_if( NULL == m );
|
||||||
|
ck_assert_int_gt( m->endpoint , 0 ); // should not be an endpoint
|
||||||
m = rtree_match( n , "/not_found", strlen("/not_found") );
|
|
||||||
fail_if( NULL == m ); // should be the node of "/"
|
|
||||||
ck_assert_int_eq( m->endpoint , 0 ); // should not be an endpoint
|
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
@ -144,44 +178,33 @@ START_TEST (test_rtree_insert_pathn)
|
||||||
{
|
{
|
||||||
node * n = rtree_create(10);
|
node * n = rtree_create(10);
|
||||||
|
|
||||||
// printf("Inserting /foo/bar\n");
|
info("Inserting /foo/bar\n");
|
||||||
rtree_insert_pathn(n, "/foo/bar", strlen("/foo/bar"), NULL);
|
rtree_insert_path(n, "/foo/bar", NULL);
|
||||||
// rtree_dump(n, 0);
|
// rtree_dump(n, 0);
|
||||||
|
|
||||||
// printf("Inserting /foo/zoo\n");
|
info("Inserting /foo/zoo\n");
|
||||||
rtree_insert_pathn(n, "/foo/zoo", strlen("/foo/zoo"), NULL);
|
rtree_insert_path(n, "/foo/zoo", NULL);
|
||||||
// rtree_dump(n, 0);
|
// rtree_dump(n, 0);
|
||||||
|
|
||||||
// printf("Inserting /f/id\n");
|
info("Inserting /f/id\n");
|
||||||
rtree_insert_pathn(n, "/f/id", strlen("/f/id") , NULL);
|
rtree_insert_path(n, "/f/id" , NULL);
|
||||||
// rtree_dump(n, 0);
|
// rtree_dump(n, 0);
|
||||||
|
|
||||||
// printf("Inserting /post/{id}\n");
|
info("Inserting /post/{id}\n");
|
||||||
rtree_insert_pathn(n, "/post/{id}", strlen("/post/{id}"), NULL);
|
rtree_insert_pathn(n, "/post/{id}", strlen("/post/{id}"), NULL);
|
||||||
// rtree_dump(n, 0);
|
// rtree_dump(n, 0);
|
||||||
|
|
||||||
// printf("Inserting /post/{handle}\n");
|
info("Inserting /post/{handle}\n");
|
||||||
rtree_insert_pathn(n, "/post/{handle}", strlen("/post/{handle}"), NULL);
|
rtree_insert_pathn(n, "/post/{handle}", strlen("/post/{handle}"), NULL);
|
||||||
// rtree_dump(n, 0);
|
// rtree_dump(n, 0);
|
||||||
|
|
||||||
// printf("Inserting /post/{handle}-{id}\n");
|
info("Inserting /post/{handle}-{id}\n");
|
||||||
rtree_insert_pathn(n, "/post/{handle}-{id}", strlen("/post/{handle}-{id}"), NULL);
|
rtree_insert_pathn(n, "/post/{handle}-{id}", strlen("/post/{handle}-{id}"), NULL);
|
||||||
rtree_compile(n);
|
rtree_compile(n);
|
||||||
// rtree_dump(n, 0);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
fail_if( rtree_lookup(n , "/a/jj/kk" , strlen("/a/jj/kk") ) == NULL );
|
|
||||||
fail_if( rtree_lookup(n , "/a/jj" , strlen("/a/jj") ) != NULL );
|
|
||||||
fail_if( rtree_lookup(n , "/a/jj/kk/ll" , strlen("/a/jj/kk/ll") ) != NULL );
|
|
||||||
fail_if( rtree_lookup(n, "/xxxx", strlen("xxxx") ) != NULL );
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// fail_if( node_find_edge(n, "/add") == NULL );
|
|
||||||
// fail_if( node_find_edge(n, "/bar") != NULL );
|
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
rtree_dump(n, 0);
|
||||||
|
#endif
|
||||||
rtree_free(n);
|
rtree_free(n);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
@ -191,60 +214,431 @@ END_TEST
|
||||||
|
|
||||||
START_TEST (test_route_split)
|
START_TEST (test_route_split)
|
||||||
{
|
{
|
||||||
token_array *t;
|
str_array *t;
|
||||||
|
|
||||||
t = split_route_pattern("/blog", strlen("/blog") );
|
t = split_route_pattern("/blog", strlen("/blog") );
|
||||||
fail_if( t == NULL );
|
fail_if( t == NULL );
|
||||||
token_array_dump(t);
|
str_array_dump(t);
|
||||||
token_array_free(t);
|
str_array_free(t);
|
||||||
|
|
||||||
t = split_route_pattern("/foo/{id}", strlen("/foo/{id}") );
|
t = split_route_pattern("/foo/{id}", strlen("/foo/{id}") );
|
||||||
fail_if( t == NULL );
|
fail_if( t == NULL );
|
||||||
token_array_dump(t);
|
str_array_dump(t);
|
||||||
fail_if( t->len != 2 );
|
fail_if( t->len != 2 );
|
||||||
token_array_free(t);
|
str_array_free(t);
|
||||||
|
|
||||||
t = split_route_pattern("/foo/bar/{id}", strlen("/foo/bar/{id}") );
|
t = split_route_pattern("/foo/bar/{id}", strlen("/foo/bar/{id}") );
|
||||||
fail_if( t == NULL );
|
fail_if( t == NULL );
|
||||||
token_array_dump(t);
|
str_array_dump(t);
|
||||||
fail_if( t->len != 3 );
|
fail_if( t->len != 3 );
|
||||||
token_array_free(t);
|
str_array_free(t);
|
||||||
|
|
||||||
t = split_route_pattern("/{title}", strlen("/{title}") );
|
t = split_route_pattern("/{title}", strlen("/{title}") );
|
||||||
fail_if( t == NULL );
|
fail_if( t == NULL );
|
||||||
token_array_dump(t);
|
str_array_dump(t);
|
||||||
fail_if( t->len != 1 );
|
fail_if( t->len != 1 );
|
||||||
token_array_free(t);
|
str_array_free(t);
|
||||||
|
|
||||||
t = split_route_pattern("/", strlen("/") );
|
t = split_route_pattern("/", strlen("/") );
|
||||||
fail_if( t == NULL );
|
fail_if( t == NULL );
|
||||||
token_array_dump(t);
|
str_array_dump(t);
|
||||||
fail_if( t->len != 1 );
|
fail_if( t->len != 1 );
|
||||||
token_array_free(t);
|
str_array_free(t);
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
START_TEST (test_token_array)
|
START_TEST (test_str_array)
|
||||||
{
|
{
|
||||||
token_array * l = token_array_create(3);
|
str_array * l = str_array_create(3);
|
||||||
fail_if( l == NULL );
|
fail_if( l == NULL );
|
||||||
|
|
||||||
fail_if( FALSE == token_array_append(l, strdup("abc") ) );
|
fail_if( FALSE == str_array_append(l, strdup("abc") ) );
|
||||||
fail_if( l->len != 1 );
|
fail_if( l->len != 1 );
|
||||||
|
|
||||||
fail_if( FALSE == token_array_append(l, strdup("foo") ) );
|
fail_if( FALSE == str_array_append(l, strdup("foo") ) );
|
||||||
fail_if( l->len != 2 );
|
fail_if( l->len != 2 );
|
||||||
|
|
||||||
fail_if( FALSE == token_array_append(l, strdup("bar") ) );
|
fail_if( FALSE == str_array_append(l, strdup("bar") ) );
|
||||||
fail_if( l->len != 3 );
|
fail_if( l->len != 3 );
|
||||||
|
|
||||||
fail_if( FALSE == token_array_append(l, strdup("zoo") ) );
|
fail_if( FALSE == str_array_append(l, strdup("zoo") ) );
|
||||||
fail_if( l->len != 4 );
|
fail_if( l->len != 4 );
|
||||||
|
|
||||||
fail_if( FALSE == token_array_resize(l, l->cap * 2) );
|
fail_if( FALSE == str_array_resize(l, l->cap * 2) );
|
||||||
|
|
||||||
|
str_array_free(l);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(benchmark_str)
|
||||||
|
{
|
||||||
|
match_entry * entry = calloc( sizeof(entry) , 1 );
|
||||||
|
node * n = rtree_create(1);
|
||||||
|
|
||||||
|
rtree_insert_path(n, "/foo/bar/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/bar/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/bar/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/bar/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/bar/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/bar/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/baz/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/baz/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/baz/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/baz/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/baz/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/baz/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/qux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/qux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/qux/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/qux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/qux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/qux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/quux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/quux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/quux/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/quux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/quux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/quux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/corge/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/corge/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/corge/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/corge/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/corge/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/corge/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/grault/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/grault/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/grault/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/grault/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/grault/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/grault/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/garply/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/garply/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/garply/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/garply/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/garply/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/foo/garply/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/foo/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/foo/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/foo/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/foo/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/foo/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/foo/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/baz/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/baz/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/baz/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/baz/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/baz/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/baz/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/qux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/qux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/qux/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/qux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/qux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/qux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/quux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/quux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/quux/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/quux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/quux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/quux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/corge/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/corge/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/corge/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/corge/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/corge/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/corge/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/grault/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/grault/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/grault/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/grault/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/grault/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/grault/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/garply/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/garply/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/garply/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/garply/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/garply/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/bar/garply/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/foo/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/foo/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/foo/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/foo/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/foo/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/foo/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/bar/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/bar/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/bar/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/bar/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/bar/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/bar/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/qux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/qux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/qux/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/qux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/qux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/qux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/quux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/quux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/quux/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/quux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/quux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/quux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/corge/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/corge/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/corge/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/corge/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/corge/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/corge/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/grault/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/grault/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/grault/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/grault/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/grault/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/grault/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/garply/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/garply/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/garply/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/garply/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/garply/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/baz/garply/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/foo/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/foo/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/foo/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/foo/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/foo/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/foo/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/bar/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/bar/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/bar/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/bar/corge", (void*) 999);
|
||||||
|
rtree_insert_path(n, "/qux/bar/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/bar/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/baz/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/baz/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/baz/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/baz/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/baz/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/baz/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/quux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/quux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/quux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/quux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/quux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/quux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/corge/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/corge/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/corge/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/corge/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/corge/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/corge/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/grault/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/grault/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/grault/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/grault/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/grault/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/grault/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/garply/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/garply/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/garply/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/garply/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/garply/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/qux/garply/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/foo/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/foo/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/foo/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/foo/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/foo/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/foo/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/bar/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/bar/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/bar/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/bar/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/bar/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/bar/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/baz/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/baz/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/baz/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/baz/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/baz/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/baz/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/qux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/qux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/qux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/qux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/qux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/qux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/corge/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/corge/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/corge/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/corge/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/corge/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/corge/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/grault/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/grault/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/grault/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/grault/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/grault/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/grault/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/garply/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/garply/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/garply/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/garply/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/garply/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/quux/garply/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/foo/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/foo/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/foo/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/foo/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/foo/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/foo/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/bar/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/bar/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/bar/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/bar/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/bar/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/bar/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/baz/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/baz/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/baz/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/baz/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/baz/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/baz/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/qux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/qux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/qux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/qux/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/qux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/qux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/quux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/quux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/quux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/quux/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/quux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/quux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/grault/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/grault/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/grault/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/grault/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/grault/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/grault/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/garply/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/garply/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/garply/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/garply/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/garply/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/corge/garply/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/foo/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/foo/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/foo/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/foo/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/foo/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/foo/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/bar/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/bar/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/bar/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/bar/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/bar/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/bar/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/baz/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/baz/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/baz/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/baz/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/baz/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/baz/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/qux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/qux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/qux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/qux/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/qux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/qux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/quux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/quux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/quux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/quux/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/quux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/quux/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/corge/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/corge/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/corge/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/corge/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/corge/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/corge/garply", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/garply/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/garply/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/garply/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/garply/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/garply/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/grault/garply/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/foo/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/foo/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/foo/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/foo/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/foo/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/foo/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/bar/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/bar/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/bar/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/bar/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/bar/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/bar/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/baz/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/baz/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/baz/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/baz/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/baz/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/baz/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/qux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/qux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/qux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/qux/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/qux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/qux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/quux/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/quux/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/quux/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/quux/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/quux/corge", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/quux/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/corge/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/corge/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/corge/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/corge/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/corge/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/corge/grault", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/grault/foo", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/grault/bar", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/grault/baz", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/grault/qux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/grault/quux", NULL);
|
||||||
|
rtree_insert_path(n, "/garply/grault/corge", NULL);
|
||||||
|
|
||||||
|
rtree_compile(n);
|
||||||
|
// rtree_dump(n, 0);
|
||||||
|
// match_entry *entry = calloc( sizeof(entry) , 1 );
|
||||||
|
|
||||||
|
node *m;
|
||||||
|
m = rtree_match(n , "/qux/bar/corge", strlen("/qux/bar/corge"), NULL);
|
||||||
|
fail_if( m == NULL );
|
||||||
|
// rtree_dump( m, 0 );
|
||||||
|
ck_assert_int_eq( (int) m->route_ptr, 999 );
|
||||||
|
|
||||||
|
|
||||||
|
printf("Benchmarking...\n");
|
||||||
|
double s = microtime();
|
||||||
|
unsigned int N = 5000000;
|
||||||
|
for (int i = 0; i < 5000000 ; i++ ) {
|
||||||
|
rtree_match(n , "/qux/bar/corge", strlen("/qux/bar/corge"), NULL);
|
||||||
|
}
|
||||||
|
double e = microtime();
|
||||||
|
|
||||||
|
printf("%.2f i/sec\n", e - s / N );
|
||||||
|
printf("%lf seconds\n", e - s );
|
||||||
|
|
||||||
|
FILE *fp = fopen("bench_str.csv", "a+");
|
||||||
|
fprintf(fp, "%.2f,\"%s\"\n", e - s / N, "using strcmp" );
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
token_array_free(l);
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
@ -253,7 +647,7 @@ Suite* r3_suite (void) {
|
||||||
|
|
||||||
TCase *tcase = tcase_create("testcase");
|
TCase *tcase = tcase_create("testcase");
|
||||||
tcase_add_test(tcase, test_route_split);
|
tcase_add_test(tcase, test_route_split);
|
||||||
tcase_add_test(tcase, test_token_array);
|
tcase_add_test(tcase, test_str_array);
|
||||||
tcase_add_test(tcase, test_ltrim_slash);
|
tcase_add_test(tcase, test_ltrim_slash);
|
||||||
tcase_add_test(tcase, test_node_construct_uniq);
|
tcase_add_test(tcase, test_node_construct_uniq);
|
||||||
tcase_add_test(tcase, test_node_find_edge);
|
tcase_add_test(tcase, test_node_find_edge);
|
||||||
|
@ -261,6 +655,8 @@ Suite* r3_suite (void) {
|
||||||
tcase_add_test(tcase, test_compile_slug);
|
tcase_add_test(tcase, test_compile_slug);
|
||||||
tcase_add_test(tcase, test_compile);
|
tcase_add_test(tcase, test_compile);
|
||||||
|
|
||||||
|
tcase_add_test(tcase, benchmark_str);
|
||||||
|
|
||||||
suite_add_tcase(suite, tcase);
|
suite_add_tcase(suite, tcase);
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
|
|
Loading…
Reference in a new issue