parent
12947c74d0
commit
fd9388437e
4 changed files with 53 additions and 37 deletions
|
@ -626,3 +626,7 @@
|
||||||
1447156411,13229275.90,5858750.37,66576.25,2523350.73
|
1447156411,13229275.90,5858750.37,66576.25,2523350.73
|
||||||
1447156432,13556025.90,5873947.56,62601.55,2487130.01
|
1447156432,13556025.90,5873947.56,62601.55,2487130.01
|
||||||
1447156745,13744909.39,5913103.69,66576.25,2551782.92
|
1447156745,13744909.39,5913103.69,66576.25,2551782.92
|
||||||
|
1447158285,11638128.71,5241775.30,71089.90,2321077.83
|
||||||
|
1447158396,13539837.29,5874704.47,47662.55,2533571.93
|
||||||
|
1447158415,14054879.53,5952300.47,41527.76,2571669.83
|
||||||
|
1447158461,14000558.11,5739623.36,53092.46,2529610.40
|
||||||
|
|
Can't render this file because it has a wrong number of fields in line 447.
|
|
@ -28,7 +28,7 @@ typedef struct _node node;
|
||||||
typedef struct _route route;
|
typedef struct _route route;
|
||||||
|
|
||||||
struct _node {
|
struct _node {
|
||||||
edge ** edges;
|
edge * edges;
|
||||||
// edge ** edge_table;
|
// edge ** edge_table;
|
||||||
char * combined_pattern;
|
char * combined_pattern;
|
||||||
pcre * pcre_pattern;
|
pcre * pcre_pattern;
|
||||||
|
@ -123,7 +123,7 @@ edge * r3_node_connectl(node * n, const char * pat, int len, int strdup, node *c
|
||||||
|
|
||||||
edge * r3_node_find_edge(const node * n, const char * pat, int pat_len);
|
edge * r3_node_find_edge(const node * n, const char * pat, int pat_len);
|
||||||
|
|
||||||
void r3_node_append_edge(node *n, edge *child);
|
edge * r3_node_append_edge(node *n, edge *child);
|
||||||
|
|
||||||
|
|
||||||
edge * r3_node_find_common_prefix(node *n, const char *path, int path_len, int *prefix_len, char **errstr);
|
edge * r3_node_find_common_prefix(node *n, const char *path, int path_len, int *prefix_len, char **errstr);
|
||||||
|
@ -171,6 +171,8 @@ bool r3_node_has_slug_edges(const node *n);
|
||||||
|
|
||||||
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child);
|
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child);
|
||||||
|
|
||||||
|
void r3_edge_initl(edge *e, const char * pattern, int pattern_len, node * child);
|
||||||
|
|
||||||
node * r3_edge_branch(edge *e, int dl);
|
node * r3_edge_branch(edge *e, int dl);
|
||||||
|
|
||||||
void r3_edge_free(edge * edge);
|
void r3_edge_free(edge * edge);
|
||||||
|
|
19
src/edge.c
19
src/edge.c
|
@ -24,11 +24,20 @@
|
||||||
#define CHECK_PTR(ptr) if (ptr == NULL) return NULL;
|
#define CHECK_PTR(ptr) if (ptr == NULL) return NULL;
|
||||||
|
|
||||||
|
|
||||||
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child) {
|
|
||||||
|
void r3_edge_initl(edge *e, const char * pattern, int pattern_len, node * child)
|
||||||
|
{
|
||||||
|
e->pattern = (char*) pattern;
|
||||||
|
e->pattern_len = pattern_len;
|
||||||
|
e->opcode = 0;
|
||||||
|
e->child = child;
|
||||||
|
e->has_slug = r3_path_contains_slug_char(e->pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child)
|
||||||
|
{
|
||||||
edge * e = (edge*) zmalloc( sizeof(edge) );
|
edge * e = (edge*) zmalloc( sizeof(edge) );
|
||||||
|
|
||||||
CHECK_PTR(e);
|
CHECK_PTR(e);
|
||||||
|
|
||||||
e->pattern = (char*) pattern;
|
e->pattern = (char*) pattern;
|
||||||
e->pattern_len = pattern_len;
|
e->pattern_len = pattern_len;
|
||||||
e->opcode = 0;
|
e->opcode = 0;
|
||||||
|
@ -61,8 +70,8 @@ node * r3_edge_branch(edge *e, int dl) {
|
||||||
|
|
||||||
// Migrate the child edges to the new edge we just created.
|
// Migrate the child edges to the new edge we just created.
|
||||||
for (int i = 0 ; i < e->child->edge_len ; i++) {
|
for (int i = 0 ; i < e->child->edge_len ; i++) {
|
||||||
r3_node_append_edge(new_child, e->child->edges[i]);
|
r3_node_append_edge(new_child, &e->child->edges[i]);
|
||||||
e->child->edges[i] = NULL;
|
// e->child->edges[i] = NULL;
|
||||||
}
|
}
|
||||||
e->child->edge_len = 0;
|
e->child->edge_len = 0;
|
||||||
|
|
||||||
|
|
57
src/node.c
57
src/node.c
|
@ -47,7 +47,7 @@ node * r3_tree_create(int cap) {
|
||||||
node * n = (node*) zmalloc( sizeof(node) );
|
node * n = (node*) zmalloc( sizeof(node) );
|
||||||
CHECK_PTR(n);
|
CHECK_PTR(n);
|
||||||
|
|
||||||
n->edges = (edge**) zmalloc( sizeof(edge*) * cap );
|
n->edges = (edge*) zmalloc(sizeof(edge) * cap);
|
||||||
CHECK_PTR(n->edges);
|
CHECK_PTR(n->edges);
|
||||||
n->edge_len = 0;
|
n->edge_len = 0;
|
||||||
n->edge_cap = cap;
|
n->edge_cap = cap;
|
||||||
|
@ -65,12 +65,9 @@ node * r3_tree_create(int cap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void r3_tree_free(node * tree) {
|
void r3_tree_free(node * tree) {
|
||||||
for (int i = 0 ; i < tree->edge_len ; i++ ) {
|
if (tree->edges) {
|
||||||
if (tree->edges[i]) {
|
|
||||||
r3_edge_free(tree->edges[ i ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zfree(tree->edges);
|
zfree(tree->edges);
|
||||||
|
}
|
||||||
zfree(tree->routes);
|
zfree(tree->routes);
|
||||||
if (tree->pcre_pattern) {
|
if (tree->pcre_pattern) {
|
||||||
pcre_free(tree->pcre_pattern);
|
pcre_free(tree->pcre_pattern);
|
||||||
|
@ -104,23 +101,29 @@ edge * r3_node_connectl(node * n, const char * pat, int len, int dupl, node *chi
|
||||||
}
|
}
|
||||||
e = r3_edge_createl(pat, len, child);
|
e = r3_edge_createl(pat, len, child);
|
||||||
CHECK_PTR(e);
|
CHECK_PTR(e);
|
||||||
r3_node_append_edge(n, e);
|
edge *e2 = r3_node_append_edge(n, e);
|
||||||
return e;
|
zfree(e);
|
||||||
|
return e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void r3_node_append_edge(node *n, edge *e) {
|
edge * r3_node_append_edge(node *n, edge *e)
|
||||||
|
{
|
||||||
if (n->edges == NULL) {
|
if (n->edges == NULL) {
|
||||||
n->edge_cap = 3;
|
n->edge_cap = 3;
|
||||||
n->edges = zmalloc(sizeof(edge) * n->edge_cap);
|
n->edges = zmalloc(sizeof(edge) * n->edge_cap);
|
||||||
}
|
}
|
||||||
if (n->edge_len >= n->edge_cap) {
|
if (n->edge_len >= n->edge_cap) {
|
||||||
n->edge_cap *= 2;
|
n->edge_cap *= 2;
|
||||||
edge ** p = zrealloc(n->edges, sizeof(edge) * n->edge_cap);
|
edge * p = zrealloc(n->edges, sizeof(edge) * n->edge_cap);
|
||||||
if(p) {
|
if(p) {
|
||||||
n->edges = p;
|
n->edges = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n->edges[ n->edge_len++ ] = e;
|
|
||||||
|
// r3_edge_initl(
|
||||||
|
// copy 'edge' into the edge array
|
||||||
|
n->edges[n->edge_len] = *e;
|
||||||
|
return &n->edges[n->edge_len++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,15 +133,12 @@ void r3_node_append_edge(node *n, edge *e) {
|
||||||
* if "pat" is a slug, we should compare with the specified pattern.
|
* if "pat" is a slug, we should compare with the specified pattern.
|
||||||
*/
|
*/
|
||||||
edge * r3_node_find_edge(const node * n, const char * pat, int pat_len) {
|
edge * r3_node_find_edge(const node * n, const char * pat, int pat_len) {
|
||||||
edge * e;
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0 ; i < n->edge_len ; i++ ) {
|
for (i = 0 ; i < n->edge_len ; i++ ) {
|
||||||
e = n->edges[i];
|
|
||||||
|
|
||||||
// there is a case: "{foo}" vs "{foo:xxx}",
|
// there is a case: "{foo}" vs "{foo:xxx}",
|
||||||
// we should return the match result: full-match or partial-match
|
// we should return the match result: full-match or partial-match
|
||||||
if ( strcmp(e->pattern, pat) == 0 ) {
|
if (strcmp(n->edges[i].pattern, pat) == 0) {
|
||||||
return e;
|
return &n->edges[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -146,6 +146,7 @@ edge * r3_node_find_edge(const node * n, const char * pat, int pat_len) {
|
||||||
|
|
||||||
int r3_tree_compile(node *n, char **errstr)
|
int r3_tree_compile(node *n, char **errstr)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool use_slug = r3_node_has_slug_edges(n);
|
bool use_slug = r3_node_has_slug_edges(n);
|
||||||
if ( use_slug ) {
|
if ( use_slug ) {
|
||||||
|
@ -157,8 +158,8 @@ int r3_tree_compile(node *n, char **errstr)
|
||||||
n->combined_pattern = NULL;
|
n->combined_pattern = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0 ; i < n->edge_len ; i++ ) {
|
for (i = 0 ; i < n->edge_len ; i++ ) {
|
||||||
if ( (ret = r3_tree_compile(n->edges[i]->child, errstr)) ) {
|
if ((ret = r3_tree_compile(n->edges[i].child, errstr))) {
|
||||||
return ret; // stop here if error occurs
|
return ret; // stop here if error occurs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +186,7 @@ int r3_tree_compile_patterns(node * n, char **errstr) {
|
||||||
int opcode_cnt = 0;
|
int opcode_cnt = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < n->edge_len ; i++) {
|
for (; i < n->edge_len ; i++) {
|
||||||
e = n->edges[i];
|
e = &n->edges[i];
|
||||||
if (e->opcode) {
|
if (e->opcode) {
|
||||||
opcode_cnt++;
|
opcode_cnt++;
|
||||||
}
|
}
|
||||||
|
@ -286,7 +287,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
|
||||||
|
|
||||||
for (i = n->edge_len; i--; ) {
|
for (i = n->edge_len; i--; ) {
|
||||||
pp = path;
|
pp = path;
|
||||||
e = n->edges[i];
|
e = &n->edges[i];
|
||||||
switch(e->opcode) {
|
switch(e->opcode) {
|
||||||
case OP_EXPECT_NOSLASH:
|
case OP_EXPECT_NOSLASH:
|
||||||
while (*pp != '/' && pp < pp_end) pp++;
|
while (*pp != '/' && pp < pp_end) pp++;
|
||||||
|
@ -372,7 +373,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
substring_start = path + ov[2*i];
|
substring_start = path + ov[2*i];
|
||||||
e = n->edges[i - 1];
|
e = &n->edges[i - 1];
|
||||||
|
|
||||||
if (entry && e->has_slug) {
|
if (entry && e->has_slug) {
|
||||||
// append captured token to entry
|
// append captured token to entry
|
||||||
|
@ -396,7 +397,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
|
||||||
}
|
}
|
||||||
|
|
||||||
substring_start = path + ov[2*i];
|
substring_start = path + ov[2*i];
|
||||||
e = n->edges[i - 1];
|
e = &n->edges[i - 1];
|
||||||
|
|
||||||
if (entry && e->has_slug) {
|
if (entry && e->has_slug) {
|
||||||
// append captured token to entry
|
// append captured token to entry
|
||||||
|
@ -440,10 +441,10 @@ inline edge * r3_node_find_edge_str(const node * n, const char * str, int str_le
|
||||||
char firstbyte = *str;
|
char firstbyte = *str;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = n->edge_len; i--; ) {
|
for (i = n->edge_len; i--; ) {
|
||||||
edge *e = n->edges[i];
|
edge *e = &n->edges[i];
|
||||||
if (firstbyte == e->pattern[0]) {
|
if (firstbyte == e->pattern[0]) {
|
||||||
if (strncmp(e->pattern, str, e->pattern_len) == 0 ) {
|
if (strncmp(e->pattern, str, e->pattern_len) == 0 ) {
|
||||||
return n->edges[i];
|
return &n->edges[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -531,11 +532,11 @@ edge * r3_node_find_common_prefix(node *n, const char *path, int path_len, int *
|
||||||
edge *e = NULL;
|
edge *e = NULL;
|
||||||
for(i = 0 ; i < n->edge_len ; i++ ) {
|
for(i = 0 ; i < n->edge_len ; i++ ) {
|
||||||
// ignore all edges with slug
|
// ignore all edges with slug
|
||||||
prefix = strndiff( (char*) path, n->edges[i]->pattern, n->edges[i]->pattern_len);
|
prefix = strndiff( (char*) path, n->edges[i].pattern, n->edges[i].pattern_len);
|
||||||
|
|
||||||
// no common, consider insert a new edge
|
// no common, consider insert a new edge
|
||||||
if ( prefix > 0 ) {
|
if ( prefix > 0 ) {
|
||||||
e = n->edges[i];
|
e = &n->edges[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,7 +754,7 @@ bool r3_node_has_slug_edges(const node *n) {
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
edge *e;
|
edge *e;
|
||||||
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];
|
||||||
e->has_slug = r3_path_contains_slug_char(e->pattern);
|
e->has_slug = r3_path_contains_slug_char(e->pattern);
|
||||||
if (e->has_slug)
|
if (e->has_slug)
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
|
@ -780,7 +781,7 @@ void r3_tree_dump(const node * n, int level) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
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 + 1);
|
print_indent(level + 1);
|
||||||
printf("|-\"%s\"", e->pattern);
|
printf("|-\"%s\"", e->pattern);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue