insert conditions at endpoints

This commit is contained in:
c9s 2014-05-18 12:28:12 +08:00
parent e0eca85cbc
commit 58cd893dea
4 changed files with 62 additions and 48 deletions

View file

@ -25,14 +25,14 @@ struct _node;
struct _route;
typedef struct _edge edge;
typedef struct _node node;
typedef struct _route route;
typedef struct _route condition;
struct _node {
edge ** edges;
int edge_len;
int edge_cap;
route ** conditions;
condition ** conditions;
int condition_len;
int condition_cap;
@ -48,7 +48,7 @@ struct _node {
int * ov;
/**
* the pointer of route data
* the pointer of condition data
*/
void * data;
@ -68,7 +68,7 @@ typedef struct {
int path_len; // the length of the current path
int request_method; // current request method
void * data; // route ptr
void * data; // condition ptr
char * host; // the request host
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);
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);
@ -133,7 +133,7 @@ void r3_edge_branch(edge *e, int dl);
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);
@ -142,17 +142,17 @@ match_entry * match_entry_createl(char * path, int path_len);
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_POST 2<<1

View file

@ -333,16 +333,16 @@ node * r3_node_create() {
}
route * route_create(char * path) {
return route_createl(path, strlen(path));
condition * condition_create(char * path) {
return condition_createl(path, strlen(path));
}
void route_free(route * route) {
free(route);
void condition_free(condition * condition) {
free(condition);
}
route * route_createl(char * path, int path_len) {
route * info = malloc(sizeof(route));
condition * condition_createl(char * path, int path_len) {
condition * info = malloc(sizeof(condition));
info->path = path;
info->path_len = path_len;
info->request_method = 0; // can be (GET || POST)
@ -355,20 +355,20 @@ route * route_createl(char * path, int path_len) {
return info;
}
node * r3_tree_insert_route(node *tree, route * route, void * data) {
return r3_tree_insert_pathl(tree, route->path, route->path_len, route, data);
node * r3_tree_insert_route(node *tree, condition * condition, void * 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.
*/
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;
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);
child->data = data;
child->endpoint++;
if (condition) {
r3_node_append_condition(child, condition, data);
}
return child;
} 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
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 {
// no more path to insert
e->child->endpoint++; // make it as an endpoint
e->child->data = data;
if (condition) {
r3_node_append_condition(e->child, condition, data);
}
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
c2->endpoint++;
c2->data = data;
if (condition) {
r3_node_append_condition(c2, condition, data);
}
return c2;
} else {
printf("unexpected condition.");
@ -503,9 +514,9 @@ void r3_tree_dump(node * n, int level) {
/**
* 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 ) {
return 0;
}
@ -550,8 +561,7 @@ int route_cmp(route *r1, route *r2) {
/**
* 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) {
n->condition_cap = 3;
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[ 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) );
/*
e->pattern = NULL;
e->pattern_len = 0;
e->child = child;
// e->route = NULL;
// e->condition = NULL;
*/
return e;
}

View file

@ -115,3 +115,9 @@
1400386505,11172976.25
1400386731,11184613.82
1400387044,10760384.75
1400387138,10813584.63
1400387154,10825571.07
1400387176,9958256.23
1400387232,11035725.37
1400387264,11006703.61
1400387291,11123431.08

1 1400242718 5649455.80
115 1400386505 11172976.25
116 1400386731 11184613.82
117 1400387044 10760384.75
118 1400387138 10813584.63
119 1400387154 10825571.07
120 1400387176 9958256.23
121 1400387232 11035725.37
122 1400387264 11006703.61
123 1400387291 11123431.08

View file

@ -224,22 +224,22 @@ END_TEST
START_TEST(test_route_cmp)
{
route *r1 = route_create("/blog/post");
route *r2 = route_create("/blog/post");
condition *r1 = condition_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;
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;
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);
route_free(r2);
condition_free(r1);
condition_free(r2);
}
END_TEST
@ -249,11 +249,11 @@ START_TEST(test_insert_route)
{
int var1 = 22;
int var2 = 33;
route *r1 = route_create("/blog/post");
route *r2 = route_create("/blog/post");
condition *r1 = condition_create("/blog/post");
condition *r2 = condition_create("/blog/post");
r1->request_method = METHOD_GET;
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");
@ -262,8 +262,8 @@ START_TEST(test_insert_route)
r3_tree_insert_route(n, r2, &var2);
match_entry_free(entry);
route_free(r1);
route_free(r2);
condition_free(r1);
condition_free(r2);
}
END_TEST
@ -275,7 +275,7 @@ START_TEST(benchmark_str)
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/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/baz", 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/garply", NULL, NULL);
r3_tree_insert_path(n, "/qux/baz/foo", NULL, NULL);