Compare commits
1 commit
2.0
...
edge-array
Author | SHA1 | Date | |
---|---|---|---|
|
fd9388437e |
4 changed files with 53 additions and 37 deletions
|
@ -626,3 +626,7 @@
|
|||
1447156411,13229275.90,5858750.37,66576.25,2523350.73
|
||||
1447156432,13556025.90,5873947.56,62601.55,2487130.01
|
||||
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;
|
||||
|
||||
struct _node {
|
||||
edge ** edges;
|
||||
edge * edges;
|
||||
// edge ** edge_table;
|
||||
char * combined_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);
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
|
||||
void r3_edge_initl(edge *e, const char * pattern, int pattern_len, node * child);
|
||||
|
||||
node * r3_edge_branch(edge *e, int dl);
|
||||
|
||||
void r3_edge_free(edge * edge);
|
||||
|
|
21
src/edge.c
21
src/edge.c
|
@ -24,11 +24,20 @@
|
|||
#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) );
|
||||
|
||||
CHECK_PTR(e);
|
||||
|
||||
e->pattern = (char*) pattern;
|
||||
e->pattern_len = pattern_len;
|
||||
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);
|
||||
|
||||
// Migrate the child edges to the new edge we just created.
|
||||
for ( int i = 0 ; i < e->child->edge_len ; i++ ) {
|
||||
r3_node_append_edge(new_child, e->child->edges[i]);
|
||||
e->child->edges[i] = NULL;
|
||||
for (int i = 0 ; i < e->child->edge_len ; i++) {
|
||||
r3_node_append_edge(new_child, &e->child->edges[i]);
|
||||
// e->child->edges[i] = NULL;
|
||||
}
|
||||
e->child->edge_len = 0;
|
||||
|
||||
|
|
59
src/node.c
59
src/node.c
|
@ -47,7 +47,7 @@ node * r3_tree_create(int cap) {
|
|||
node * n = (node*) zmalloc( sizeof(node) );
|
||||
CHECK_PTR(n);
|
||||
|
||||
n->edges = (edge**) zmalloc( sizeof(edge*) * cap );
|
||||
n->edges = (edge*) zmalloc(sizeof(edge) * cap);
|
||||
CHECK_PTR(n->edges);
|
||||
n->edge_len = 0;
|
||||
n->edge_cap = cap;
|
||||
|
@ -65,12 +65,9 @@ node * r3_tree_create(int cap) {
|
|||
}
|
||||
|
||||
void r3_tree_free(node * tree) {
|
||||
for (int i = 0 ; i < tree->edge_len ; i++ ) {
|
||||
if (tree->edges[i]) {
|
||||
r3_edge_free(tree->edges[ i ]);
|
||||
}
|
||||
}
|
||||
if (tree->edges) {
|
||||
zfree(tree->edges);
|
||||
}
|
||||
zfree(tree->routes);
|
||||
if (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);
|
||||
CHECK_PTR(e);
|
||||
r3_node_append_edge(n, e);
|
||||
return e;
|
||||
edge *e2 = r3_node_append_edge(n, 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) {
|
||||
n->edge_cap = 3;
|
||||
n->edges = zmalloc(sizeof(edge) * n->edge_cap);
|
||||
}
|
||||
if (n->edge_len >= n->edge_cap) {
|
||||
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) {
|
||||
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.
|
||||
*/
|
||||
edge * r3_node_find_edge(const node * n, const char * pat, int pat_len) {
|
||||
edge * e;
|
||||
int i;
|
||||
for (i = 0 ; i < n->edge_len ; i++ ) {
|
||||
e = n->edges[i];
|
||||
|
||||
// there is a case: "{foo}" vs "{foo:xxx}",
|
||||
// we should return the match result: full-match or partial-match
|
||||
if ( strcmp(e->pattern, pat) == 0 ) {
|
||||
return e;
|
||||
if (strcmp(n->edges[i].pattern, pat) == 0) {
|
||||
return &n->edges[i];
|
||||
}
|
||||
}
|
||||
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 i;
|
||||
int ret = 0;
|
||||
bool use_slug = r3_node_has_slug_edges(n);
|
||||
if ( use_slug ) {
|
||||
|
@ -157,8 +158,8 @@ int r3_tree_compile(node *n, char **errstr)
|
|||
n->combined_pattern = NULL;
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < n->edge_len ; i++ ) {
|
||||
if ( (ret = r3_tree_compile(n->edges[i]->child, errstr)) ) {
|
||||
for (i = 0 ; i < n->edge_len ; i++ ) {
|
||||
if ((ret = r3_tree_compile(n->edges[i].child, errstr))) {
|
||||
return ret; // stop here if error occurs
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +174,7 @@ int r3_tree_compile(node *n, char **errstr)
|
|||
* Return 0 if success
|
||||
*/
|
||||
int r3_tree_compile_patterns(node * n, char **errstr) {
|
||||
edge * e = NULL;
|
||||
edge *e = NULL;
|
||||
char * p;
|
||||
char * cpat = zcalloc(sizeof(char) * 64 * 3); // XXX
|
||||
if (!cpat) {
|
||||
|
@ -185,7 +186,7 @@ int r3_tree_compile_patterns(node * n, char **errstr) {
|
|||
int opcode_cnt = 0;
|
||||
int i = 0;
|
||||
for (; i < n->edge_len ; i++) {
|
||||
e = n->edges[i];
|
||||
e = &n->edges[i];
|
||||
if (e->opcode) {
|
||||
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--; ) {
|
||||
pp = path;
|
||||
e = n->edges[i];
|
||||
e = &n->edges[i];
|
||||
switch(e->opcode) {
|
||||
case OP_EXPECT_NOSLASH:
|
||||
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;
|
||||
|
||||
substring_start = path + ov[2*i];
|
||||
e = n->edges[i - 1];
|
||||
e = &n->edges[i - 1];
|
||||
|
||||
if (entry && e->has_slug) {
|
||||
// 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];
|
||||
e = n->edges[i - 1];
|
||||
e = &n->edges[i - 1];
|
||||
|
||||
if (entry && e->has_slug) {
|
||||
// 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;
|
||||
unsigned int i;
|
||||
for (i = n->edge_len; i--; ) {
|
||||
edge *e = n->edges[i];
|
||||
edge *e = &n->edges[i];
|
||||
if (firstbyte == e->pattern[0]) {
|
||||
if (strncmp(e->pattern, str, e->pattern_len) == 0 ) {
|
||||
return n->edges[i];
|
||||
return &n->edges[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -531,11 +532,11 @@ edge * r3_node_find_common_prefix(node *n, const char *path, int path_len, int *
|
|||
edge *e = NULL;
|
||||
for(i = 0 ; i < n->edge_len ; i++ ) {
|
||||
// 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
|
||||
if ( prefix > 0 ) {
|
||||
e = n->edges[i];
|
||||
e = &n->edges[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -753,7 +754,7 @@ bool r3_node_has_slug_edges(const node *n) {
|
|||
bool found = FALSE;
|
||||
edge *e;
|
||||
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);
|
||||
if (e->has_slug)
|
||||
found = TRUE;
|
||||
|
@ -780,7 +781,7 @@ void r3_tree_dump(const node * n, int level) {
|
|||
printf("\n");
|
||||
|
||||
for ( int i = 0 ; i < n->edge_len ; i++ ) {
|
||||
edge * e = n->edges[i];
|
||||
edge * e = &n->edges[i];
|
||||
print_indent(level + 1);
|
||||
printf("|-\"%s\"", e->pattern);
|
||||
|
||||
|
|
Loading…
Reference in a new issue