Add route namespace

Summary:

    type route now becomes R3Route

Related issue #63
This commit is contained in:
c9s 2015-11-18 14:16:26 +08:00
parent 29a2a934d0
commit c3ef959539
11 changed files with 76 additions and 76 deletions

View file

@ -6,7 +6,7 @@ R3
[![Coverage Status](https://coveralls.io/repos/c9s/r3/badge.svg)](https://coveralls.io/r/c9s/r3)
R3 is an URL router library with high performance, thus, it's implemented in C.
It compiles your route paths into a prefix trie.
It compiles your R3Route paths into a prefix trie.
By using the prefix tree constructed in the start-up time, you can dispatch
the path to the controller with high efficiency.
@ -47,7 +47,7 @@ R3Node *n = r3_tree_create(10);
int route_data = 3;
// insert the route path into the router tree
// insert the R3Route path into the router tree
r3_tree_insert_path(n, "/bar", &route_data); // ignore the length of path
r3_tree_insert_pathl(n, "/zoo", strlen("/zoo"), &route_data );
@ -114,7 +114,7 @@ entry->request_method = METHOD_POST;
entry->request_method = METHOD_GET | METHOD_POST;
```
When using `match_entry`, you may match the route with `r3_tree_match_entry` function:
When using `match_entry`, you may match the R3Route with `r3_tree_match_entry` function:
```c
R3Node * matched_node = r3_tree_match_entry(n, entry);
@ -141,7 +141,7 @@ n = r3_tree_create(10);
int route_data = 3;
// insert the route path into the router tree
// insert the R3Route path into the router tree
r3_tree_insert_routel(n, METHOD_GET | METHOD_POST, "/blog/post", sizeof("/blog/post") - 1, &route_data );
char *errstr = NULL;
@ -160,7 +160,7 @@ match_entry * entry = match_entry_create("/blog/post");
entry->request_method = METHOD_GET;
route *matched_route = r3_tree_match_route(n, entry);
R3Route *matched_R3Route = r3_tree_match_route(n, entry);
matched_route->data; // get the data from matched route
// free the objects at the end
@ -179,7 +179,7 @@ To specify the pattern of a slug, you may write a colon to separate the slug nam
"/user/{userId:\\d+}"
The above route will use `\d+` as its pattern.
The above R3Route will use `\d+` as its pattern.
Optimization
@ -206,7 +206,7 @@ And here is the result of the router journey:
omg 9932.9 (±4.8%) i/s - 49873 in 5.033452s
r3 uses the same route path data for benchmarking, and here is the benchmark:
r3 uses the same R3Route path data for benchmarking, and here is the benchmark:
3 runs, 5000000 iterations each run, finished in 1.308894 seconds
11460057.83 i/sec
@ -214,7 +214,7 @@ r3 uses the same route path data for benchmarking, and here is the benchmark:
### The Route Paths Of Benchmark
The route path generator is from <https://github.com/stevegraham/rails/pull/1>:
The R3Route path generator is from <https://github.com/stevegraham/rails/pull/1>:
```ruby
#!/usr/bin/env ruby
@ -242,7 +242,7 @@ Function prefix mapping
Rendering Routes With Graphviz
---------------------------------------
The `r3_tree_render_file` API let you render the whole route trie into a image.
The `r3_tree_render_file` API let you render the whole R3Route trie into a image.
To use graphviz, you need to enable graphviz while you run `configure`:
@ -347,7 +347,7 @@ $ret = r3_dispatch($rs, '/blog/post/3' );
list($complete, $route, $variables) = $ret;
// matched conditions aren't done yet
list($error, $message) = r3_validate($route); // validate route conditions
list($error, $message) = r3_validate($route); // validate R3Route conditions
if ( $error ) {
echo $message; // "Method not allowed", "...";
}

View file

@ -13,7 +13,7 @@ Architecture: any
Depends: libr3 (= ${binary:Version})
Description: Development files for libr3
libr3 (https://github.com/c9s/r3) is an URL router library with high
performance, thus, it's implemented in C. It compiles your route paths into
performance, thus, it's implemented in C. It compiles your R3Route paths into
a prefix trie.
.
This package contains header files for libr3.
@ -24,5 +24,5 @@ Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: High performance URL routing library written in C.
libr3 (https://github.com/c9s/r3) is an URL router library with high
performance, thus, it's implemented in C. It compiles your route paths into
performance, thus, it's implemented in C. It compiles your R3Route paths into
a prefix trie.

View file

@ -9,7 +9,7 @@ void example_1() {
// create a router tree with 10 children capacity (this capacity can grow dynamically)
r3::Tree tree(10);
// insert the route path into the router tree
// insert the R3Route path into the router tree
int route_data_1 = 1;
tree.insert_path("/bar", &route_data_1); // ignore the length of path
@ -65,7 +65,7 @@ void example_2() {
// create a router tree with 10 children capacity (this capacity can grow dynamically)
r3::Tree tree(10);
// insert the route path into the router tree
// insert the R3Route path into the router tree
int route_data = 1;
tree.insert_routel(METHOD_GET | METHOD_POST, "/blog/post",
sizeof("/blog/post") - 1, &route_data);

View file

@ -43,7 +43,7 @@ struct _node;
struct _route;
typedef struct _edge R3Edge;
typedef struct _node R3Node;
typedef struct _route route;
typedef struct _R3Route R3Route;
struct _node {
R3Edge * edges;
@ -58,8 +58,8 @@ struct _node {
unsigned int ov_cnt; // capture vector array size for pcre
route ** routes;
// the pointer of route data
R3Route ** routes;
// the pointer of R3Route data
void * data;
// almost less than 255
@ -79,7 +79,7 @@ struct _edge {
unsigned int has_slug; // 4byte
} __attribute__((aligned(64)));
struct _route {
struct _R3Route {
char * path;
int path_len;
@ -100,7 +100,7 @@ typedef struct {
int path_len; // the length of the current path
int request_method; // current request method
void * data; // route ptr
void * data; // R3Route ptr
char * host; // the request host
int host_len;
@ -138,9 +138,9 @@ R3Node * r3_tree_insert_pathl(R3Node *tree, const char *path, int path_len, void
route * r3_tree_insert_routel(R3Node * tree, int method, const char *path, int path_len, void *data);
R3Route * r3_tree_insert_routel(R3Node * tree, int method, const char *path, int path_len, void *data);
route * r3_tree_insert_routel_ex(R3Node * tree, int method, const char *path, int path_len, void *data, char **errstr);
R3Route * r3_tree_insert_routel_ex(R3Node * tree, int method, const char *path, int path_len, void *data, char **errstr);
#define r3_tree_insert_routel(n, method, path, path_len, data) r3_tree_insert_routel_ex(n, method, path, path_len, data, NULL)
@ -152,7 +152,7 @@ route * r3_tree_insert_routel_ex(R3Node * tree, int method, const char *path, in
/**
* The private API to insert a path
*/
R3Node * r3_tree_insert_pathl_ex(R3Node *tree, const char *path, int path_len, route * route, void * data, char ** errstr);
R3Node * r3_tree_insert_pathl_ex(R3Node *tree, const char *path, int path_len, R3Route * route, void * data, char ** errstr);
void r3_tree_dump(const R3Node * n, int level);
@ -185,18 +185,18 @@ void r3_edge_free(R3Edge * edge);
route * r3_route_create(const char * path);
R3Route * r3_route_create(const char * path);
route * r3_route_createl(const char * path, int path_len);
R3Route * r3_route_createl(const char * path, int path_len);
void r3_node_append_route(R3Node * n, route * route);
void r3_node_append_route(R3Node * n, R3Route * route);
void r3_route_free(route * route);
void r3_route_free(R3Route * route);
int r3_route_cmp(const route *r1, const match_entry *r2);
int r3_route_cmp(const R3Route *r1, const match_entry *r2);
route * r3_tree_match_route(const R3Node *n, match_entry * entry);
R3Route * r3_tree_match_route(const R3Node *n, match_entry * entry);
#define r3_route_create(p) r3_route_createl(p, strlen(p))

View file

@ -38,7 +38,7 @@ namespace r3 {
T* p_;
};
typedef Base<R3Node> Node;
typedef Base<route> Route;
typedef Base<R3Route> Route;
class MatchEntry : public Base<match_entry> {
public:

View file

@ -13,7 +13,7 @@
json_object * r3_edge_to_json_object(const edge * e);
json_object * r3_node_to_json_object(const node * n);
json_object * r3_route_to_json_object(const route * r);
json_object * r3_route_to_json_object(const R3Route * r);
const char * r3_node_to_json_string_ext(const node * n, int options);
const char * r3_node_to_json_pretty_string(const node * n);

View file

@ -407,8 +407,8 @@ PHP_FUNCTION(r3_match)
}
zval *z_route;
z_route = php_r3_match(z_routes, path, path_len TSRMLS_CC);
if ( z_route != NULL ) {
z_R3Route = php_r3_match(z_routes, path, path_len TSRMLS_CC);
if ( z_R3Route != NULL ) {
*return_value = *z_route;
zval_copy_ctor(return_value);
return;
@ -438,7 +438,7 @@ PHP_FUNCTION(r3_persistent_dispatch)
char *ns, *filename, *path;
int ns_len, filename_len, path_len;
zval *mux = NULL;
zval *route = NULL;
zval *R3Route = NULL;
zval *z_path = NULL;
/* parse parameters */
@ -463,15 +463,15 @@ PHP_FUNCTION(r3_persistent_dispatch)
ZVAL_STRINGL(z_path, path ,path_len, 1); // no copy
// XXX: pass return_value to the method call, so we don't need to copy
route = call_mux_method(mux, "dispatch" , sizeof("dispatch"), 1 , z_path, NULL, NULL TSRMLS_CC);
R3Route = call_mux_method(mux, "dispatch" , sizeof("dispatch"), 1 , z_path, NULL, NULL TSRMLS_CC);
zval_ptr_dtor(&z_path);
if ( route ) {
if ( R3Route ) {
*return_value = *route;
zval_copy_ctor(return_value);
return;
}
// route not found
// R3Route not found
RETURN_FALSE;
}
@ -649,7 +649,7 @@ inline zval * php_r3_match(zval *z_routes, char *path, int path_len TSRMLS_DC) {
// tell garbage collector to collect it, we need to use pcre_subpats later.
// check conditions only when route option is provided
// check conditions only when R3Route option is provided
if ( zend_hash_index_find( Z_ARRVAL_PP(z_route_pp), 3, (void**) &z_route_options_pp) == SUCCESS ) {
if ( zend_hash_num_elements(Z_ARRVAL_PP(z_route_options_pp)) ) {
if ( 0 == validate_request_method( z_route_options_pp, current_request_method TSRMLS_CC) ) {

View file

@ -81,7 +81,7 @@ zend_class_entry ** get_pattern_compiler_ce(TSRMLS_D) {
return ce_pattern_compiler;
}
// Returns compiled route zval
// Returns compiled R3Route zval
zval * compile_route_pattern(zval *z_pattern, zval *z_options, zend_class_entry **ce_pattern_compiler TSRMLS_DC)
{
// zend_class_entry **ce_pattern_compiler;
@ -92,10 +92,10 @@ zval * compile_route_pattern(zval *z_pattern, zval *z_options, zend_class_entry
}
}
zval *z_compiled_route = NULL; // will be an array
zval *z_compiled_R3Route = NULL; // will be an array
zend_call_method( NULL, *ce_pattern_compiler, NULL, "compile", strlen("compile"), &z_compiled_route, 2, z_pattern, z_options TSRMLS_CC );
if ( z_compiled_route == NULL ) {
if ( z_compiled_R3Route == NULL ) {
return NULL;
} else if ( Z_TYPE_P(z_compiled_route) == IS_NULL ) {
zval_ptr_dtor(&z_compiled_route);
@ -467,7 +467,7 @@ PHP_METHOD(Mux, mount) {
// zval for new route
zval *z_new_routes;
// zval for route item
// zval for R3Route item
zval **z_is_pcre; // route[0]
zval **z_route_pattern;
zval **z_route_callback;
@ -514,10 +514,10 @@ PHP_METHOD(Mux, mount) {
// $routeArgs = PatternCompiler::compile($newPattern,
// array_merge_recursive($route[3], $options) );
zval *z_compiled_route = compile_route_pattern(z_new_pattern, *z_route_options, ce_pattern_compiler TSRMLS_CC);
zval *z_compiled_R3Route = compile_route_pattern(z_new_pattern, *z_route_options, ce_pattern_compiler TSRMLS_CC);
if ( z_compiled_route == NULL || Z_TYPE_P(z_compiled_route) == IS_NULL ) {
if ( z_compiled_R3Route == NULL || Z_TYPE_P(z_compiled_route) == IS_NULL ) {
php_error( E_ERROR, "Cannot compile pattern: %s", new_pattern);
}
@ -535,7 +535,7 @@ PHP_METHOD(Mux, mount) {
Z_ADDREF_P(z_compiled_route);
Z_ADDREF_P(z_new_routes);
// create new route and append to mux->routes
// create new R3Route and append to mux->routes
add_index_bool(z_new_routes, 0 , 1); // pcre flag == false
add_index_zval(z_new_routes, 1, *z_compiled_route_pattern);
add_index_zval(z_new_routes, 2 , *z_route_callback);
@ -558,7 +558,7 @@ PHP_METHOD(Mux, mount) {
int new_pattern_len = pattern_len + Z_STRLEN_PP(z_route_pattern);
// Merge the mount options with the route options
// Merge the mount options with the R3Route options
zval *z_new_route_options;
MAKE_STD_ZVAL(z_new_route_options);
array_init(z_new_route_options);
@ -681,11 +681,11 @@ PHP_METHOD(Mux, getRoute) {
}
zval *z_routes_by_id = NULL;
zval **z_route = NULL;
zval **z_R3Route = NULL;
z_routes_by_id = zend_read_property( ce_r3_mux , this_ptr, "routesById", sizeof("routesById")-1, 1 TSRMLS_CC);
// php_var_dump(&z_routes_by_id, 1 TSRMLS_CC);
if ( zend_hash_find( Z_ARRVAL_P(z_routes_by_id) , route_id, route_id_len + 1, (void**) &z_route ) == SUCCESS ) {
if ( zend_hash_find( Z_ARRVAL_P(z_routes_by_id) , route_id, route_id_len + 1, (void**) &z_R3Route ) == SUCCESS ) {
*return_value = **z_route;
zval_copy_ctor(return_value);
return;
@ -788,7 +788,7 @@ PHP_METHOD(Mux, compile) {
zend_call_method( NULL, NULL, NULL, "usort", strlen("usort"), &rv, 2,
z_routes, z_sort_callback TSRMLS_CC );
zval_ptr_dtor(&z_sort_callback); // recycle sort callback zval
// php_error(E_ERROR,"route sort failed.");
// php_error(E_ERROR,"R3Route sort failed.");
// zend_update_property(ce_r3_mux, getThis(), "routes", sizeof("routes")-1, z_routes TSRMLS_CC);
}
@ -843,7 +843,7 @@ PHP_METHOD(Mux, dispatch) {
int path_len;
zval *z_path;
zval *z_return_route = NULL;
zval *z_return_R3Route = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
RETURN_FALSE;
@ -856,7 +856,7 @@ PHP_METHOD(Mux, dispatch) {
zend_hash_quick_find( &ce_r3_mux->function_table, "match", sizeof("match"), zend_inline_hash_func(ZEND_STRS("match")), (void **) &fe);
zend_call_method( &this_ptr, ce_r3_mux, &fe, "match", strlen("match"), &z_return_route, 1, z_path, NULL TSRMLS_CC );
if ( ! z_return_route || Z_TYPE_P(z_return_route) == IS_NULL ) {
if ( ! z_return_R3Route || Z_TYPE_P(z_return_route) == IS_NULL ) {
zval_ptr_dtor(&z_path);
RETURN_NULL();
}
@ -908,11 +908,11 @@ PHP_METHOD(Mux, dispatch) {
zval *z_substr;
if ( zend_hash_quick_find( Z_ARRVAL_PP(z_options) , "vars", sizeof("vars"), zend_inline_hash_func(ZEND_STRS("vars")), (void**) &z_route_vars ) == FAILURE ) {
php_error(E_ERROR, "require route vars");
php_error(E_ERROR, "require R3Route vars");
RETURN_FALSE;
}
if ( zend_hash_index_find( Z_ARRVAL_PP(z_options) , 0 , (void**) &z_route_vars_0 ) == FAILURE ) {
php_error(E_ERROR, "require route vars[0]");
php_error(E_ERROR, "require R3Route vars[0]");
RETURN_FALSE;
}
@ -955,7 +955,7 @@ PHP_METHOD(Mux, dispatch) {
}
}
if ( z_return_route ) {
if ( z_return_R3Route ) {
*return_value = *z_return_route;
zval_copy_ctor(return_value);
}
@ -972,7 +972,7 @@ PHP_METHOD(Mux, match) {
}
zval **z_route_pp = NULL;
zval *z_route = NULL;
zval *z_R3Route = NULL;
if ( zend_hash_find( Z_ARRVAL_P( zend_read_property(ce_r3_mux, this_ptr, "staticRoutes", sizeof("staticRoutes") - 1, 1 TSRMLS_CC) ), path, path_len, (void**)&z_route_pp) == SUCCESS ) {
if ( Z_TYPE_PP(z_route_pp) != IS_NULL ) {
*return_value = **z_route_pp;
@ -981,8 +981,8 @@ PHP_METHOD(Mux, match) {
return;
}
}
z_route = php_r3_match(zend_read_property(ce_r3_mux , this_ptr , "routes", sizeof("routes")-1, 1 TSRMLS_CC), path, path_len TSRMLS_CC);
if ( z_route != NULL ) {
z_R3Route = php_r3_match(zend_read_property(ce_r3_mux , this_ptr , "routes", sizeof("routes")-1, 1 TSRMLS_CC), path, path_len TSRMLS_CC);
if ( z_R3Route != NULL ) {
*return_value = *z_route;
zval_copy_ctor(return_value);
Z_ADDREF_P(z_route);
@ -1058,7 +1058,7 @@ PHP_METHOD(Mux, appendPCRERoute) {
zend_call_method( NULL, *ce_pattern_compiler, NULL, "compile", strlen("compile"), &rv, 1, z_pattern, NULL TSRMLS_CC );
if ( rv == NULL || Z_TYPE_P(rv) == IS_NULL ) {
zend_throw_exception(ce_r3_exception, "Can not compile route pattern", 0 TSRMLS_CC);
zend_throw_exception(ce_r3_exception, "Can not compile R3Route pattern", 0 TSRMLS_CC);
RETURN_FALSE;
}
add_next_index_zval(z_routes, rv);
@ -1115,9 +1115,9 @@ inline void mux_add_route(INTERNAL_FUNCTION_PARAMETERS)
MAKE_STD_ZVAL(z_pattern);
ZVAL_STRINGL(z_pattern, pattern, pattern_len, 1);
zval *z_compiled_route = compile_route_pattern(z_pattern, z_options, NULL TSRMLS_CC);
if ( z_compiled_route == NULL ) {
zend_throw_exception(ce_r3_exception, "Unable to compile route pattern.", 0 TSRMLS_CC);
zval *z_compiled_R3Route = compile_route_pattern(z_pattern, z_options, NULL TSRMLS_CC);
if ( z_compiled_R3Route == NULL ) {
zend_throw_exception(ce_r3_exception, "Unable to compile R3Route pattern.", 0 TSRMLS_CC);
RETURN_FALSE;
}
zval_ptr_dtor(&z_pattern);
@ -1160,7 +1160,7 @@ inline void mux_add_route(INTERNAL_FUNCTION_PARAMETERS)
add_index_zval( z_new_route, 3 , z_options);
add_next_index_zval(z_routes, z_new_route);
// if there is no option specified in z_options, we can add the route to our static route hash
// if there is no option specified in z_options, we can add the R3Route to our static R3Route hash
if ( zend_hash_num_elements(Z_ARRVAL_P(z_options)) ) {
zval * z_static_routes = zend_read_property(ce_r3_mux, this_ptr, "staticRoutes", sizeof("staticRoutes")-1, 1 TSRMLS_CC);
if ( z_static_routes ) {
@ -1173,7 +1173,7 @@ inline void mux_add_route(INTERNAL_FUNCTION_PARAMETERS)
zval * z_routes_by_id = zend_read_property(ce_r3_mux, this_ptr, "routesById", sizeof("routesById")-1, 1 TSRMLS_CC);
/*
zval *id_route = NULL;
zval *id_R3Route = NULL;
ALLOC_ZVAL(id_route);
ZVAL_COPY_VALUE(id_route, z_new_route);
zval_copy_ctor(id_route);

View file

@ -9,7 +9,7 @@
#include "r3.h"
#include "r3_json.h"
json_object * r3_route_to_json_object(const route * r) {
json_object * r3_route_to_json_object(const R3Route * r) {
json_object *obj;
obj = json_object_new_object();

View file

@ -434,7 +434,7 @@ R3Node * r3_tree_matchl(const R3Node * n, const char * path, int path_len, match
route * r3_tree_match_route(const R3Node *tree, match_entry * entry) {
R3Route * r3_tree_match_route(const R3Node *tree, match_entry * entry) {
R3Node *n;
int i;
n = r3_tree_match_entry(tree, entry);
@ -483,12 +483,12 @@ R3Node * r3_node_create() {
return n;
}
void r3_route_free(route * route) {
void r3_route_free(R3Route * route) {
zfree(route);
}
route * r3_route_createl(const char * path, int path_len) {
route * info = zmalloc(sizeof(route));
R3Route * r3_route_createl(const char * path, int path_len) {
R3Route * info = zmalloc(sizeof(R3Route));
CHECK_PTR(info);
info->path = (char*) path;
info->path_len = path_len;
@ -510,8 +510,8 @@ route * r3_route_createl(const char * path, int path_len) {
*
* method (int): METHOD_GET, METHOD_POST, METHOD_PUT, METHOD_DELETE ...
*/
route * r3_tree_insert_routel_ex(R3Node *tree, int method, const char *path, int path_len, void *data, char **errstr) {
route *r = r3_route_createl(path, path_len);
R3Route * r3_tree_insert_routel_ex(R3Node *tree, int method, const char *path, int path_len, void *data, char **errstr) {
R3Route *r = r3_route_createl(path, path_len);
CHECK_PTR(r);
r->request_method = method; // ALLOW GET OR POST METHOD
R3Node * ret = r3_tree_insert_pathl_ex(tree, path, path_len, r, data, errstr);
@ -601,7 +601,7 @@ R3Edge * r3_node_find_common_prefix(R3Node *n, const char *path, int path_len, i
/**
* Return the last inserted node.
*/
R3Node * r3_tree_insert_pathl_ex(R3Node *tree, const char *path, int path_len, route * route, void * data, char **errstr)
R3Node * r3_tree_insert_pathl_ex(R3Node *tree, const char *path, int path_len, R3Route * route, void * data, char **errstr)
{
R3Node * n = tree;
@ -824,7 +824,7 @@ void r3_tree_dump(const R3Node * n, int level) {
*
* -1 == different route
*/
inline int r3_route_cmp(const route *r1, const match_entry *r2) {
inline int r3_route_cmp(const R3Route *r1, const match_entry *r2) {
if (r1->request_method != 0) {
if (0 == (r1->request_method & r2->request_method) ) {
return -1;
@ -855,14 +855,14 @@ inline int r3_route_cmp(const route *r1, const match_entry *r2) {
/**
*
*/
void r3_node_append_route(R3Node * n, route * r) {
void r3_node_append_route(R3Node * n, R3Route * r) {
if (n->routes == NULL) {
n->route_cap = 3;
n->routes = zmalloc(sizeof(route) * n->route_cap);
n->routes = zmalloc(sizeof(R3Route) * n->route_cap);
}
if (n->route_len >= n->route_cap) {
n->route_cap *= 2;
n->routes = zrealloc(n->routes, sizeof(route) * n->route_cap);
n->routes = zrealloc(n->routes, sizeof(R3Route) * n->route_cap);
}
n->routes[ n->route_len++ ] = r;
}

View file

@ -608,7 +608,7 @@ END_TEST
START_TEST(test_route_cmp)
{
route *r1 = r3_route_create("/blog/post");
R3Route *r1 = r3_route_create("/blog/post");
match_entry * m = match_entry_create("/blog/post");
fail_if( r3_route_cmp(r1, m) == -1, "should match");
@ -732,7 +732,7 @@ START_TEST(test_insert_route)
r3_tree_insert_route(n, METHOD_POST, "/blog/post", &var2);
match_entry * entry;
route *r;
R3Route *r;
entry = match_entry_create("/blog/post");
entry->request_method = METHOD_GET;