support simple opcode

This commit is contained in:
c9s 2014-05-23 15:48:26 +08:00
parent 333fabd795
commit b394be57cb
3 changed files with 70 additions and 20 deletions

View file

@ -479,3 +479,7 @@
1400820886,12274457.34,2393445.83,55188.21
1400820922,12218386.22,2604565.56,77672.30
1400820933,12443155.46,2361317.46,45590.26
1400829105,12110496.08,4797414.85,38479.85
1400829117,12258758.55,4129968.45,59074.70
1400829143,12339827.27,4775224.01,55924.05
1400831278,11421287.15,4742488.93,39945.75

Can't render this file because it has a wrong number of fields in line 447.

View file

@ -3,9 +3,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
// Jemalloc memory management
// #include <jemalloc/jemalloc.h>
#include <ctype.h>
// PCRE
#include <pcre.h>
@ -160,8 +158,13 @@ void r3_tree_compile_patterns(node * n) {
p++;
edge *e = NULL;
int opcode_cnt = 0;
for ( int i = 0 ; i < n->edge_len ; i++ ) {
e = n->edges[i];
if ( e->opcode )
opcode_cnt++;
if ( e->has_slug ) {
// compile "foo/{slug}" to "foo/[^/]+"
char * slug_pat = slug_compile(e->pattern, e->pattern_len);
@ -183,16 +186,15 @@ void r3_tree_compile_patterns(node * n) {
info("pattern: %s\n",cpat);
// if all edges use opcode, we should skip the combined_pattern.
/*
if ( opcode_cnt == n->edge_len ) {
zfree(cpat);
return;
// zfree(cpat);
n->compare_type = NODE_COMPARE_OPCODE;
} else {
n->compare_type = NODE_COMPARE_PCRE;
}
*/
n->combined_pattern = cpat;
const char *error;
int erroffset;
unsigned int option_bits = 0;
@ -258,6 +260,47 @@ node * r3_tree_matchl(const node * n, char * path, int path_len, match_entry * e
int rc;
int i;
int ov_cnt;
int restlen;
if (n->compare_type == NODE_COMPARE_OPCODE ) {
for (i = 0; i < n->edge_len ; i++ ) {
char *pp = path;
char *pp_end = path + path_len;
e = n->edges[i];
switch(e->opcode) {
case OP_EXPECT_NOSLASH:
while (*pp != '/' && pp < pp_end) {
pp++;
}
break;
case OP_EXPECT_DIGITS:
while ( isdigit(*pp) && pp < pp_end) {
pp++;
}
break;
case OP_EXPECT_WORDS:
while ( (isdigit(*pp) || isalpha(*pp)) && pp < pp_end) {
pp++;
}
break;
case OP_EXPECT_NODASH:
while (*pp != '-' && pp < pp_end) {
pp++;
}
break;
}
if ( (pp - path) > 0) {
restlen = pp_end - pp;
if (entry) {
str_array_append(entry->vars , zstrndup(path, pp - path));
}
if (restlen == 0) {
return e->child && e->child->endpoint > 0 ? e->child : NULL;
}
return r3_tree_matchl(e->child, pp, pp_end - pp, entry);
}
}
}
// if the pcre_pattern is found, and the pointer is not NULL, then it's
// pcre pattern node, we use pcre_exec to match the nodes
@ -301,7 +344,7 @@ node * r3_tree_matchl(const node * n, char * path, int path_len, match_entry * e
// info("%2d: %.*s\n", i, substring_length, substring_start);
if ( substring_length > 0) {
int restlen = path_len - ov[1]; // fully match to the end
restlen = path_len - ov[1]; // fully match to the end
// info("matched item => restlen:%d edges:%d i:%d\n", restlen, n->edge_len, i);
e = n->edges[i - 1];
@ -322,7 +365,7 @@ node * r3_tree_matchl(const node * n, char * path, int path_len, match_entry * e
}
if ( (e = r3_node_find_edge_str(n, path, path_len)) != NULL ) {
int restlen = path_len - e->pattern_len;
restlen = path_len - e->pattern_len;
if (restlen == 0) {
return e->child && e->child->endpoint > 0 ? e->child : NULL;
}

View file

@ -42,22 +42,25 @@ START_TEST (test_r3_node_find_edge)
END_TEST
START_TEST (test_compile)
{
str_array *t;
static node * create_simple_str_tree() {
node * n;
n = r3_tree_create(10);
node *m;
edge *e ;
r3_tree_insert_path(n, "/zoo", NULL);
r3_tree_insert_path(n, "/foo", NULL);
r3_tree_insert_path(n, "/bar", NULL);
r3_tree_compile(n);
fail_if( n->combined_pattern );
fail_if( NULL == r3_node_find_edge_str(n, "/", strlen("/") ) );
return n;
}
START_TEST (test_compile)
{
str_array *t;
node * n = create_simple_str_tree();
node *m;
edge *e ;
#ifdef DEBUG
r3_tree_dump(n, 0);