insert conditions at endpoints
This commit is contained in:
parent
e0eca85cbc
commit
58cd893dea
4 changed files with 62 additions and 48 deletions
26
include/r3.h
26
include/r3.h
|
@ -25,14 +25,14 @@ struct _node;
|
||||||
struct _route;
|
struct _route;
|
||||||
typedef struct _edge edge;
|
typedef struct _edge edge;
|
||||||
typedef struct _node node;
|
typedef struct _node node;
|
||||||
typedef struct _route route;
|
typedef struct _route condition;
|
||||||
|
|
||||||
struct _node {
|
struct _node {
|
||||||
edge ** edges;
|
edge ** edges;
|
||||||
int edge_len;
|
int edge_len;
|
||||||
int edge_cap;
|
int edge_cap;
|
||||||
|
|
||||||
route ** conditions;
|
condition ** conditions;
|
||||||
int condition_len;
|
int condition_len;
|
||||||
int condition_cap;
|
int condition_cap;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ struct _node {
|
||||||
int * ov;
|
int * ov;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the pointer of route data
|
* the pointer of condition data
|
||||||
*/
|
*/
|
||||||
void * data;
|
void * data;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ typedef struct {
|
||||||
int path_len; // the length of the current path
|
int path_len; // the length of the current path
|
||||||
int request_method; // current request method
|
int request_method; // current request method
|
||||||
|
|
||||||
void * data; // route ptr
|
void * data; // condition ptr
|
||||||
|
|
||||||
char * host; // the request host
|
char * host; // the request host
|
||||||
int host_len;
|
int host_len;
|
||||||
|
@ -105,9 +105,9 @@ edge * r3_node_find_edge(node * n, char * pat);
|
||||||
|
|
||||||
void r3_node_append_edge(node *n, edge *child);
|
void r3_node_append_edge(node *n, edge *child);
|
||||||
|
|
||||||
node * r3_tree_insert_path(node *tree, char *path, route * route, void * data);
|
node * r3_tree_insert_path(node *tree, char *path, condition * condition, void * data);
|
||||||
|
|
||||||
node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, void * data);
|
node * r3_tree_insert_pathl(node *tree, char *path, int path_len, condition * condition, void * data);
|
||||||
|
|
||||||
void r3_tree_dump(node * n, int level);
|
void r3_tree_dump(node * n, int level);
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ void r3_edge_branch(edge *e, int dl);
|
||||||
void r3_edge_free(edge * edge);
|
void r3_edge_free(edge * edge);
|
||||||
|
|
||||||
|
|
||||||
node * r3_tree_insert_route(node *tree, route * route, void * data);
|
node * r3_tree_insert_route(node *tree, condition * condition, void * data);
|
||||||
|
|
||||||
match_entry * match_entry_createl(char * path, int path_len);
|
match_entry * match_entry_createl(char * path, int path_len);
|
||||||
|
|
||||||
|
@ -142,17 +142,17 @@ match_entry * match_entry_createl(char * path, int path_len);
|
||||||
void match_entry_free(match_entry * entry);
|
void match_entry_free(match_entry * entry);
|
||||||
|
|
||||||
|
|
||||||
route * route_create(char * path);
|
condition * condition_create(char * path);
|
||||||
|
|
||||||
route * route_createl(char * path, int path_len);
|
condition * condition_createl(char * path, int path_len);
|
||||||
|
|
||||||
int route_cmp(route *r1, route *r2);
|
int condition_cmp(condition *r1, condition *r2);
|
||||||
|
|
||||||
edge * r3_edge_route_create(route * route, node * child);
|
edge * r3_edge_route_create(condition * condition, node * child);
|
||||||
|
|
||||||
node * r3_node_append_condition(node * n, route * route, void * data);
|
void r3_node_append_condition(node * n, condition * condition, void * data);
|
||||||
|
|
||||||
void route_free(route * route);
|
void condition_free(condition * condition);
|
||||||
|
|
||||||
#define METHOD_GET 2
|
#define METHOD_GET 2
|
||||||
#define METHOD_POST 2<<1
|
#define METHOD_POST 2<<1
|
||||||
|
|
50
src/node.c
50
src/node.c
|
@ -333,16 +333,16 @@ node * r3_node_create() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
route * route_create(char * path) {
|
condition * condition_create(char * path) {
|
||||||
return route_createl(path, strlen(path));
|
return condition_createl(path, strlen(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void route_free(route * route) {
|
void condition_free(condition * condition) {
|
||||||
free(route);
|
free(condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
route * route_createl(char * path, int path_len) {
|
condition * condition_createl(char * path, int path_len) {
|
||||||
route * info = malloc(sizeof(route));
|
condition * info = malloc(sizeof(condition));
|
||||||
info->path = path;
|
info->path = path;
|
||||||
info->path_len = path_len;
|
info->path_len = path_len;
|
||||||
info->request_method = 0; // can be (GET || POST)
|
info->request_method = 0; // can be (GET || POST)
|
||||||
|
@ -355,20 +355,20 @@ route * route_createl(char * path, int path_len) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
node * r3_tree_insert_route(node *tree, route * route, void * data) {
|
node * r3_tree_insert_route(node *tree, condition * condition, void * data) {
|
||||||
return r3_tree_insert_pathl(tree, route->path, route->path_len, route, data);
|
return r3_tree_insert_pathl(tree, condition->path, condition->path_len, condition, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
node * r3_tree_insert_path(node *tree, char *path, route * route, void * data)
|
node * r3_tree_insert_path(node *tree, char *path, condition * condition, void * data)
|
||||||
{
|
{
|
||||||
return r3_tree_insert_pathl(tree, path, strlen(path) , route , data);
|
return r3_tree_insert_pathl(tree, path, strlen(path) , condition , data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last inserted node.
|
* Return the last inserted node.
|
||||||
*/
|
*/
|
||||||
node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, void * data)
|
node * r3_tree_insert_pathl(node *tree, char *path, int path_len, condition * condition, void * data)
|
||||||
{
|
{
|
||||||
node * n = tree;
|
node * n = tree;
|
||||||
edge * e = NULL;
|
edge * e = NULL;
|
||||||
|
@ -404,6 +404,10 @@ node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route,
|
||||||
info("edge not found, insert one: %s\n", path);
|
info("edge not found, insert one: %s\n", path);
|
||||||
child->data = data;
|
child->data = data;
|
||||||
child->endpoint++;
|
child->endpoint++;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
r3_node_append_condition(child, condition, data);
|
||||||
|
}
|
||||||
return child;
|
return child;
|
||||||
} else if ( offset == e->pattern_len ) { // fully-equal to the pattern of the edge
|
} else if ( offset == e->pattern_len ) { // fully-equal to the pattern of the edge
|
||||||
|
|
||||||
|
@ -412,11 +416,14 @@ node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route,
|
||||||
|
|
||||||
// there are something more we can insert
|
// there are something more we can insert
|
||||||
if ( subpath_len > 0 ) {
|
if ( subpath_len > 0 ) {
|
||||||
return r3_tree_insert_pathl(e->child, subpath, subpath_len, route, data);
|
return r3_tree_insert_pathl(e->child, subpath, subpath_len, condition, data);
|
||||||
} else {
|
} else {
|
||||||
// no more path to insert
|
// no more path to insert
|
||||||
e->child->endpoint++; // make it as an endpoint
|
e->child->endpoint++; // make it as an endpoint
|
||||||
e->child->data = data;
|
e->child->data = data;
|
||||||
|
if (condition) {
|
||||||
|
r3_node_append_condition(e->child, condition, data);
|
||||||
|
}
|
||||||
return e->child;
|
return e->child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +458,10 @@ node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route,
|
||||||
// move n->edges to c1
|
// move n->edges to c1
|
||||||
c2->endpoint++;
|
c2->endpoint++;
|
||||||
c2->data = data;
|
c2->data = data;
|
||||||
|
|
||||||
|
if (condition) {
|
||||||
|
r3_node_append_condition(c2, condition, data);
|
||||||
|
}
|
||||||
return c2;
|
return c2;
|
||||||
} else {
|
} else {
|
||||||
printf("unexpected condition.");
|
printf("unexpected condition.");
|
||||||
|
@ -503,9 +514,9 @@ void r3_tree_dump(node * n, int level) {
|
||||||
/**
|
/**
|
||||||
* return 0 == equal
|
* return 0 == equal
|
||||||
*
|
*
|
||||||
* -1 == different route
|
* -1 == different condition
|
||||||
*/
|
*/
|
||||||
int route_cmp(route *r1, route *r2) {
|
int condition_cmp(condition *r1, condition *r2) {
|
||||||
if ( r1 == r2 ) {
|
if ( r1 == r2 ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -550,8 +561,7 @@ int route_cmp(route *r1, route *r2) {
|
||||||
/**
|
/**
|
||||||
* Create a data only node.
|
* Create a data only node.
|
||||||
*/
|
*/
|
||||||
node * r3_node_append_condition(node * n, route * route, void * data) {
|
void r3_node_append_condition(node * n, condition * condition, void * data) {
|
||||||
/*
|
|
||||||
if (!n->conditions) {
|
if (!n->conditions) {
|
||||||
n->condition_cap = 3;
|
n->condition_cap = 3;
|
||||||
n->conditions = malloc(sizeof(condition) * n->condition_cap);
|
n->conditions = malloc(sizeof(condition) * n->condition_cap);
|
||||||
|
@ -561,20 +571,18 @@ node * r3_node_append_condition(node * n, route * route, void * data) {
|
||||||
n->conditions = realloc(n->conditions, sizeof(condition) * n->condition_cap);
|
n->conditions = realloc(n->conditions, sizeof(condition) * n->condition_cap);
|
||||||
}
|
}
|
||||||
n->conditions[ n->condition_len++ ] = condition;
|
n->conditions[ n->condition_len++ ] = condition;
|
||||||
*/
|
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a route-only edge. (without pattern)
|
* Create a condition-only edge. (without pattern)
|
||||||
*/
|
*/
|
||||||
edge * r3_edge_route_create(route * route, node * child) {
|
edge * r3_edge_route_create(condition * condition, node * child) {
|
||||||
edge * e = (edge*) malloc( sizeof(edge) );
|
edge * e = (edge*) malloc( sizeof(edge) );
|
||||||
/*
|
/*
|
||||||
e->pattern = NULL;
|
e->pattern = NULL;
|
||||||
e->pattern_len = 0;
|
e->pattern_len = 0;
|
||||||
e->child = child;
|
e->child = child;
|
||||||
// e->route = NULL;
|
// e->condition = NULL;
|
||||||
*/
|
*/
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,3 +115,9 @@
|
||||||
1400386505,11172976.25
|
1400386505,11172976.25
|
||||||
1400386731,11184613.82
|
1400386731,11184613.82
|
||||||
1400387044,10760384.75
|
1400387044,10760384.75
|
||||||
|
1400387138,10813584.63
|
||||||
|
1400387154,10825571.07
|
||||||
|
1400387176,9958256.23
|
||||||
|
1400387232,11035725.37
|
||||||
|
1400387264,11006703.61
|
||||||
|
1400387291,11123431.08
|
||||||
|
|
|
|
@ -224,22 +224,22 @@ END_TEST
|
||||||
|
|
||||||
START_TEST(test_route_cmp)
|
START_TEST(test_route_cmp)
|
||||||
{
|
{
|
||||||
route *r1 = route_create("/blog/post");
|
condition *r1 = condition_create("/blog/post");
|
||||||
route *r2 = route_create("/blog/post");
|
condition *r2 = condition_create("/blog/post");
|
||||||
|
|
||||||
fail_if( route_cmp(r1, r2) == -1, "should be the same");
|
fail_if( condition_cmp(r1, r2) == -1, "should be the same");
|
||||||
|
|
||||||
r1->request_method = METHOD_GET;
|
r1->request_method = METHOD_GET;
|
||||||
r2->request_method = METHOD_GET;
|
r2->request_method = METHOD_GET;
|
||||||
fail_if( route_cmp(r1, r2) == -1, "should be the same");
|
fail_if( condition_cmp(r1, r2) == -1, "should be the same");
|
||||||
|
|
||||||
r1->request_method = METHOD_GET;
|
r1->request_method = METHOD_GET;
|
||||||
r2->request_method = METHOD_POST;
|
r2->request_method = METHOD_POST;
|
||||||
fail_if( route_cmp(r1, r2) == 0, "should be different");
|
fail_if( condition_cmp(r1, r2) == 0, "should be different");
|
||||||
|
|
||||||
|
|
||||||
route_free(r1);
|
condition_free(r1);
|
||||||
route_free(r2);
|
condition_free(r2);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
@ -249,11 +249,11 @@ START_TEST(test_insert_route)
|
||||||
{
|
{
|
||||||
int var1 = 22;
|
int var1 = 22;
|
||||||
int var2 = 33;
|
int var2 = 33;
|
||||||
route *r1 = route_create("/blog/post");
|
condition *r1 = condition_create("/blog/post");
|
||||||
route *r2 = route_create("/blog/post");
|
condition *r2 = condition_create("/blog/post");
|
||||||
r1->request_method = METHOD_GET;
|
r1->request_method = METHOD_GET;
|
||||||
r2->request_method = METHOD_POST;
|
r2->request_method = METHOD_POST;
|
||||||
fail_if( route_cmp(r1, r2) == 0, "should be different");
|
fail_if( condition_cmp(r1, r2) == 0, "should be different");
|
||||||
|
|
||||||
match_entry * entry = match_entry_create("/blog/post");
|
match_entry * entry = match_entry_create("/blog/post");
|
||||||
|
|
||||||
|
@ -262,8 +262,8 @@ START_TEST(test_insert_route)
|
||||||
r3_tree_insert_route(n, r2, &var2);
|
r3_tree_insert_route(n, r2, &var2);
|
||||||
|
|
||||||
match_entry_free(entry);
|
match_entry_free(entry);
|
||||||
route_free(r1);
|
condition_free(r1);
|
||||||
route_free(r2);
|
condition_free(r2);
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ START_TEST(benchmark_str)
|
||||||
node * n = r3_tree_create(1);
|
node * n = r3_tree_create(1);
|
||||||
|
|
||||||
|
|
||||||
int route_data = 999;
|
int condition_data = 999;
|
||||||
|
|
||||||
r3_tree_insert_path(n, "/foo/bar/baz", NULL, NULL);
|
r3_tree_insert_path(n, "/foo/bar/baz", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/foo/bar/qux", NULL, NULL);
|
r3_tree_insert_path(n, "/foo/bar/qux", NULL, NULL);
|
||||||
|
@ -412,7 +412,7 @@ r3_tree_insert_path(n, "/qux/foo/garply", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/qux/bar/foo", NULL, NULL);
|
r3_tree_insert_path(n, "/qux/bar/foo", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/qux/bar/baz", NULL, NULL);
|
r3_tree_insert_path(n, "/qux/bar/baz", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/qux/bar/quux", NULL, NULL);
|
r3_tree_insert_path(n, "/qux/bar/quux", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/qux/bar/corge", NULL, &route_data);
|
r3_tree_insert_path(n, "/qux/bar/corge", NULL, &condition_data);
|
||||||
r3_tree_insert_path(n, "/qux/bar/grault", NULL, NULL);
|
r3_tree_insert_path(n, "/qux/bar/grault", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/qux/bar/garply", NULL, NULL);
|
r3_tree_insert_path(n, "/qux/bar/garply", NULL, NULL);
|
||||||
r3_tree_insert_path(n, "/qux/baz/foo", NULL, NULL);
|
r3_tree_insert_path(n, "/qux/baz/foo", NULL, NULL);
|
||||||
|
|
Loading…
Reference in a new issue