Make edges as an array

Fixes: #89
This commit is contained in:
c9s 2015-11-10 20:29:07 +08:00
parent 12947c74d0
commit fd9388437e
4 changed files with 53 additions and 37 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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;
@ -60,9 +69,9 @@ node * r3_edge_branch(edge *e, int dl) {
e1 = r3_edge_createl(zstrndup(s1, s1_len), s1_len, new_child); e1 = r3_edge_createl(zstrndup(s1, s1_len), s1_len, new_child);
// 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;

View file

@ -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]) { zfree(tree->edges);
r3_edge_free(tree->edges[ i ]);
}
} }
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
} }
} }
@ -173,7 +174,7 @@ int r3_tree_compile(node *n, char **errstr)
* Return 0 if success * Return 0 if success
*/ */
int r3_tree_compile_patterns(node * n, char **errstr) { int r3_tree_compile_patterns(node * n, char **errstr) {
edge * e = NULL; edge *e = NULL;
char * p; char * p;
char * cpat = zcalloc(sizeof(char) * 64 * 3); // XXX char * cpat = zcalloc(sizeof(char) * 64 * 3); // XXX
if (!cpat) { if (!cpat) {
@ -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);