Пример #1
0
END_TEST

START_TEST (test_node_construct_and_free)
{
    node * n = r3_tree_create(10);
    node * another_tree = r3_tree_create(3);
    r3_tree_free(n);
    r3_tree_free(another_tree);
}
Пример #2
0
END_TEST

START_TEST (test_r3_node_construct_uniq)
{
    node * n = r3_tree_create(10);

    node * child = r3_tree_create(3);

    // fail_if( r3_node_add_child(n, strdup("/add") , child) != NULL );
    // fail_if( r3_node_add_child(n, strdup("/add") , child) != NULL );

    r3_tree_free(n);
}
Пример #3
0
END_TEST

START_TEST (test_r3_node_find_edge)
{
    node * n = r3_tree_create(10);

    node * child = r3_tree_create(3);

    fail_if( r3_node_add_child(n, strdup("/add") , child) == FALSE );

    fail_if( r3_node_find_edge(n, "/add") == NULL );
    fail_if( r3_node_find_edge(n, "/bar") != NULL );

    r3_tree_free(n);
}
Пример #4
0
END_TEST




START_TEST (test_r3_tree_insert_pathl)
{
    node * n = r3_tree_create(10);

    r3_tree_insert_path(n, "/foo/bar",  NULL);
    // r3_tree_dump(n, 0);

    r3_tree_insert_path(n, "/foo/zoo",  NULL);
    // r3_tree_dump(n, 0);

    r3_tree_insert_path(n, "/f/id" ,  NULL);
    // r3_tree_dump(n, 0);

    r3_tree_insert_path(n, "/post/{id}", NULL);
    // r3_tree_dump(n, 0);

    r3_tree_insert_path(n, "/post/{handle}", NULL);

    r3_tree_insert_path(n, "/post/{handle}-{id}", NULL);
    r3_tree_compile(n);

#ifdef DEBUG
    r3_tree_dump(n, 0);
#endif
    r3_tree_free(n);
}
Пример #5
0
END_TEST


START_TEST (test_pcre_patterns_insert)
{
    node * n = r3_tree_create(10);

    // r3_tree_insert_path(n, "/foo-{user}-{id}", NULL, NULL);
    // r3_tree_dump(n, 0);
    r3_tree_insert_path(n, "/post/{handle:\\d+}-{id:\\d+}", NULL);
    r3_tree_compile(n);
    r3_tree_dump(n, 0);

    node *matched;
    matched = r3_tree_matchl(n, "/post/111-222", strlen("/post/111-222"), NULL);
    ck_assert(matched);
    ck_assert_int_gt(matched->endpoint, 0);

    // incomplete string shouldn't match
    matched = r3_tree_matchl(n, "/post/111-", strlen("/post/111-"), NULL);
    ck_assert(matched);
    ck_assert_int_eq(matched->endpoint, 0);

    r3_tree_free(n);
}
Пример #6
0
END_TEST




START_TEST(test_insert_route)
{
    int   var1 = 22;
    int   var2 = 33;
    route *r1 = r3_route_create("/blog/post");
    route *r2 = r3_route_create("/blog/post");
    r1->request_method = METHOD_GET;
    r2->request_method = METHOD_POST;

    match_entry * entry = match_entry_create("/blog/post");
    entry->request_method = METHOD_GET;

    node * n = r3_tree_create(2);
    r3_tree_insert_route(n, r1, &var1);
    r3_tree_insert_route(n, r2, &var2);

    route *c = r3_tree_match_route(n, entry);
    fail_if(c == NULL);

    match_entry_free(entry);
    r3_route_free(r1);
    r3_route_free(r2);
}
Пример #7
0
END_TEST



START_TEST (test_compile_fail)
{
    node * n = r3_tree_create(10);

    node * ret;

    ret = r3_tree_insert_path(n, "/foo/{idx}/{idy:)}",  NULL);
    ck_assert(ret);

    ret = r3_tree_insert_path(n, "/foo/{idx}/{idh:(}",  NULL);
    ck_assert(ret);

    char * errstr = NULL;
    r3_tree_compile(n, &errstr);
    ck_assert(errstr);
    fprintf(stderr, "Compile failed: %s\n", errstr);
    free(errstr);

    r3_tree_dump(n, 0);
    r3_tree_free(n);
}
Пример #8
0
Файл: edge.c Проект: czchen/r3
/**
 * branch the edge pattern at "dl" offset,
 * insert a dummy child between the edges.
 *
 *
 * A -> [prefix..suffix] -> B
 * A -> [prefix] -> B -> [suffix] -> New Child (Copy Data, Edges from B)
 *
 */
node * r3_edge_branch(edge *e, int dl) {
    node *new_child;
    edge *e1;
    char * s1 = e->pattern + dl;
    int s1_len = 0;

    edge **tmp_edges = e->child->edges;
    int   tmp_edge_len = e->child->edge_len;

    // the suffix edge of the leaf
    new_child = r3_tree_create(3);
    s1_len = e->pattern_len - dl;
    e1 = r3_edge_create(zstrndup(s1, s1_len), s1_len, new_child);

    // Migrate the child edges to the new edge we just created.
    for ( int i = 0 ; i < tmp_edge_len ; i++ ) {
        r3_node_append_edge(new_child, tmp_edges[i]);
        e->child->edges[i] = NULL;
    }
    e->child->edge_len = 0;
    new_child->endpoint = e->child->endpoint;
    e->child->endpoint = 0; // reset endpoint

    r3_node_append_edge(e->child, e1);
    new_child->data = e->child->data; // copy data pointer
    e->child->data = NULL;

    // truncate the original edge pattern
    char *op = e->pattern;
    e->pattern = zstrndup(e->pattern, dl);
    e->pattern_len = dl;

    return new_child;
}
Пример #9
0
END_TEST



START_TEST (test_find_common_prefix_middle)
{
    node * n = r3_tree_create(10);
    edge * e = r3_edge_createl(zstrdup("/foo/{slug}/hate"), sizeof("/foo/{slug}/hate")-1, NULL);
    r3_node_append_edge(n,e);

    int prefix_len;
    edge *ret_edge = NULL;
    char *errstr = NULL;

    errstr = NULL;
    ret_edge = r3_node_find_common_prefix(n, "/foo/{slug}/bar", sizeof("/foo/{slug}/bar")-1, &prefix_len, &errstr);
    ck_assert(ret_edge);
    ck_assert_int_eq(prefix_len, 12);
    SAFE_FREE(errstr);

    errstr = NULL;
    ret_edge = r3_node_find_common_prefix(n, "/fo/{slug}/bar", sizeof("/fo/{slug}/bar")-1, &prefix_len, &errstr);
    ck_assert(ret_edge);
    ck_assert_int_eq(prefix_len, 3);
    SAFE_FREE(errstr);

    r3_tree_free(n);
}
Пример #10
0
END_TEST

static node * create_simple_str_tree() {
    node * n;
    n = r3_tree_create(10);
    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, NULL);
    return n;
}
Пример #11
0
static PyObject*
Trie_new(PyObject* type, PyObject* args, PyObject* kwds) {
    Trie *self;

    self = (Trie *)type->tp_alloc(type, 0);
    if (self != NULL) {
        // TODO: cap
        self->node = r3_tree_create(100);
    }

    return (PyObject *)self;
}
Пример #12
0
END_TEST


START_TEST(test_pcre_pattern_more)
{
    match_entry * entry;
    entry = match_entry_createl( "/user/123" , strlen("/user/123") );
    node * n = r3_tree_create(10);

    int var0 = 5;
    int var1 = 100;
    int var2 = 200;
    int var3 = 300;

    info("var0: %p\n", &var0);
    info("var1: %p\n", &var1);
    info("var2: %p\n", &var2);
    info("var3: %p\n", &var3);

    r3_tree_insert_path(n, "/user/{id:\\d+}", &var1);
    r3_tree_insert_path(n, "/user2/{id:\\d+}", &var2);
    r3_tree_insert_path(n, "/user3/{id:\\d{3}}", &var3);
    r3_tree_insert_path(n, "/user", &var0);
    r3_tree_compile(n, NULL);
    r3_tree_dump(n, 0);
    node *matched;

    matched = r3_tree_matchl(n, "/user/123", strlen("/user/123"), entry);
    ck_assert(matched);
    ck_assert(entry->vars->len > 0);
    ck_assert_str_eq(entry->vars->tokens[0],"123");

    info("matched %p\n", matched->data);
    info("matched %p\n", matched->data);
    ck_assert_int_eq( *((int*) matched->data), var1);

    matched = r3_tree_matchl(n, "/user2/123", strlen("/user2/123"), entry);
    ck_assert(matched);
    ck_assert(entry->vars->len > 0);
    ck_assert_str_eq(entry->vars->tokens[0],"123");
    ck_assert_int_eq( *((int*)matched->data), var2);

    matched = r3_tree_matchl(n, "/user3/123", strlen("/user3/123"), entry);
    ck_assert(matched);
    ck_assert(entry->vars->len > 0);
    ck_assert_str_eq(entry->vars->tokens[0],"123");
    ck_assert_int_eq( *((int*)matched->data), var3);

    r3_tree_free(n);
}
Пример #13
0
END_TEST


START_TEST (test_pcre_patterns_insert)
{
    node * n = r3_tree_create(10);

    // r3_tree_insert_path(n, "/foo-{user}-{id}", NULL, NULL);
    r3_tree_insert_path(n, "/post/{handle:\\d+}-{id:\\d+}", NULL);

    r3_tree_insert_path(n, "/post/foo", NULL);
    r3_tree_insert_path(n, "/post/bar", NULL);

    char *errstr = NULL;
    int errcode;
    errcode = r3_tree_compile(n, &errstr);
    ck_assert(errcode == 0); // no error

    // r3_tree_dump(n, 0);

    node *matched;


    matched = r3_tree_match(n, "/post/foo", NULL);
    ck_assert(matched);
    ck_assert(matched->endpoint > 0);

    matched = r3_tree_match(n, "/post/bar", NULL);
    ck_assert(matched);
    ck_assert(matched->endpoint > 0);

    matched = r3_tree_match(n, "/post/kkkfoo", NULL);
    ck_assert(!matched);

    matched = r3_tree_match(n, "/post/kkkbar", NULL);
    ck_assert(!matched);



    matched = r3_tree_matchl(n, "/post/111-222", strlen("/post/111-222"), NULL);
    ck_assert(matched);
    ck_assert(matched->endpoint > 0);

    // incomplete string shouldn't match
    matched = r3_tree_matchl(n, "/post/111-", strlen("/post/111-"), NULL);
    ck_assert(! matched);

    r3_tree_free(n);
}
Пример #14
0
END_TEST




START_TEST (test_insert_pathl)
{
    node * n = r3_tree_create(10);

    node * ret;

    ret = r3_tree_insert_path(n, "/foo/bar",  NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/foo/zoo",  NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/foo/{id}",  NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/foo/{number:\\d+}",  NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/foo/{name:\\w+}",  NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/foo/{name:\\d+}",  NULL);
    ck_assert(ret);

    ret = r3_tree_insert_path(n, "/foo/{name:\\d{5}}",  NULL);
    ck_assert(ret);

    ret = r3_tree_insert_path(n, "/foo/{idx}/{idy}",  NULL);
    ck_assert(ret);

    ret = r3_tree_insert_path(n, "/foo/{idx}/{idh}",  NULL);
    ck_assert(ret);

    ret = r3_tree_insert_path(n, "/f/id" ,  NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/post/{id}", NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/post/{handle}", NULL);
    ck_assert(ret);
    ret = r3_tree_insert_path(n, "/post/{handle}-{id}", NULL);
    ck_assert(ret);

    char * errstr = NULL;
    r3_tree_compile(n, &errstr);
    ck_assert(errstr == NULL);

    r3_tree_dump(n, 0);
    r3_tree_free(n);
}
Пример #15
0
END_TEST


START_TEST (test_incomplete_slug_path)
{
    node * n = r3_tree_create(10);

    node * ret_node;

    // r3_tree_insert_path(n, "/foo-{user}-{id}", NULL, NULL);
    ret_node = r3_tree_insert_path(n, "/post/{handle", NULL);
    assert(!ret_node);

    ret_node = r3_tree_insert_path(n, "/post/{handle:\\", NULL);
    assert(!ret_node);

    ret_node = r3_tree_insert_path(n, "/post/{handle:\\d", NULL);
    assert(!ret_node);

    ret_node = r3_tree_insert_path(n, "/post/{handle:\\d{", NULL);
    assert(!ret_node);

    ret_node = r3_tree_insert_path(n, "/post/{handle:\\d{3", NULL);
    assert(!ret_node);

    r3_tree_insert_path(n, "/post/{handle:\\d{3}", NULL);
    r3_tree_insert_path(n, "/post/{handle:\\d{3}}/{", NULL);
    r3_tree_insert_path(n, "/post/{handle:\\d{3}}/{a", NULL);
    r3_tree_insert_path(n, "/post/{handle:\\d{3}}/{a}", NULL);

    ret_node = r3_tree_insert_path(n, "/users/{idx:\\d{3}}/{idy}", NULL);
    ck_assert(ret_node);

    // OK to insert, but should return error when compiling patterns
    node * ret_node2 = r3_tree_insert_path(n, "/users/{idx:\\d{3}}/{idy:aaa}", NULL);
    ck_assert(ret_node2);
    ck_assert(ret_node2 != ret_node); // make sure it's another node


    char *errstr = NULL;
    r3_tree_compile(n, &errstr);
    ck_assert(errstr == NULL); // no error

    r3_tree_dump(n, NULL);

    r3_tree_free(n);
}
Пример #16
0
END_TEST

START_TEST (test_find_common_prefix_same_pattern2)
{
    node * n = r3_tree_create(10);
    edge * e = r3_edge_createl(zstrdup("{slug:xxx}/hate"), sizeof("{slug:xxx}/hate")-1, NULL);
    r3_node_append_edge(n,e);

    int prefix_len;
    edge *ret_edge = NULL;

    prefix_len = 0;
    ret_edge = r3_node_find_common_prefix(n, "{slug:yyy}/hate", sizeof("{slug:yyy}/hate")-1, &prefix_len, NULL);
    ck_assert(ret_edge);
    ck_assert_int_eq(prefix_len, 0);

    r3_tree_free(n);
}
Пример #17
0
END_TEST


START_TEST(test_pcre_pattern_simple)
{
    match_entry * entry;
    entry = match_entry_createl( "/user/123" , strlen("/user/123") );
    node * n = r3_tree_create(10);
    r3_tree_insert_path(n, "/user/{id:\\d+}", NULL);
    r3_tree_insert_path(n, "/user", NULL);
    r3_tree_compile(n);
    // r3_tree_dump(n, 0);
    node *matched;
    matched = r3_tree_matchl(n, "/user/123", strlen("/user/123"), entry);
    fail_if(matched == NULL);
    ck_assert_int_gt(entry->vars->len, 0);
    ck_assert_str_eq(entry->vars->tokens[0],"123");
}
Пример #18
0
/**
 * r3_edge_branch splits the edge and append the rest part as the child of the
 * first level child
 *
 * branch the edge pattern at "dl" offset,
 * and insert a dummy child between the edges.
 *
 * A -> [EDGE: abcdefg] -> B -> [EDGE:branch1], [EDGE:branch2]
 * A -> [EDGE: abcd] -> B1 -> [efg] -> B2 (new child with copied data from B)
 *
 */
R3Node * r3_edge_branch(R3Edge *e, int dl) {
    R3Node * new_child;
    R3Edge * new_edge;

    // the rest string
    char * s1 = e->pattern.base + dl;
    int s1_len = e->pattern.len - dl;

    // the suffix edge of the leaf
    new_child = r3_tree_create(3);

    new_edge = r3_node_append_edge(new_child);
    r3_edge_initl(new_edge, s1, s1_len, e->child);
    e->child = new_child;
    
    // truncate the original edge pattern
    e->pattern.len = dl;
    return new_child;
}
Пример #19
0
END_TEST

START_TEST (test_gvc_render_file)
{

    node * n = r3_tree_create(1);

    r3_tree_insert_path(n, "/foo/bar/baz",  NULL);
    r3_tree_insert_path(n, "/foo/bar/qux",  NULL);
    r3_tree_insert_path(n, "/foo/bar/quux",  NULL);
    r3_tree_insert_path(n, "/foo/bar/corge",  NULL);
    r3_tree_insert_path(n, "/foo/bar/grault",  NULL);
    r3_tree_insert_path(n, "/garply/grault/foo",  NULL);
    r3_tree_insert_path(n, "/garply/grault/bar",  NULL);
    r3_tree_insert_path(n, "/user/{id}",  NULL);
    r3_tree_insert_path(n, "/post/{title:\\w+}",  NULL);

    r3_tree_compile(n);
    r3_tree_render_file(n, "png", "check_gvc.png");
    r3_tree_free(n);
}
Пример #20
0
END_TEST

/**
 * Test for (\d{2})/([^/]+)
 */
START_TEST (test_pcre_patterns_insert_3)
{
    node * n = r3_tree_create(10);
    printf("Inserting /post/{idx:\\d{2}}/{idy}\n");
    r3_tree_insert_path(n, "/post/{idx:\\d{2}}/{idy}", NULL);
    r3_tree_dump(n, 0);

    printf("Inserting /zoo\n");
    r3_tree_insert_path(n, "/zoo", NULL);
    r3_tree_dump(n, 0);

    r3_tree_insert_path(n, "/foo", NULL);
    r3_tree_insert_path(n, "/bar", NULL);

    char *errstr = NULL;
    r3_tree_compile(n, &errstr);

    r3_tree_dump(n, 0);
    node *matched;


    matched = r3_tree_match(n, "/post/11/22", NULL);
    ck_assert((int)matched);

    matched = r3_tree_match(n, "/post/11", NULL);
    ck_assert(!matched);

    matched = r3_tree_match(n, "/post/11/", NULL);
    ck_assert(!matched);

    /*
    matched = r3_tree_match(n, "/post/113", NULL);
    ck_assert(!matched);
    */
}
Пример #21
0
END_TEST



START_TEST (test_insert_pathl_fail)
{
    node * n = r3_tree_create(10);

    node * ret;

    char *errstr = NULL;
    ret = r3_tree_insert_pathl_ex(n, "/foo/{name:\\d{5}", strlen("/foo/{name:\\d{5}"),  NULL, NULL, &errstr);
    ck_assert(ret == NULL);
    ck_assert(errstr != NULL);
    printf("%s\n", errstr); // Returns Incomplete slug pattern. PATTERN (16): '/foo/{name:\d{5}', OFFSET: 16, STATE: 1
    SAFE_FREE(errstr);

    errstr = NULL;
    r3_tree_compile(n, &errstr);
    ck_assert(errstr == NULL);

    r3_tree_free(n);
}
Пример #22
0
END_TEST


/**
 * Test for \d{2}/\d{2}
 */
START_TEST (test_pcre_patterns_insert_2)
{
    node * n = r3_tree_create(10);
    r3_tree_insert_path(n, "/post/{idx:\\d{2}}/{idy:\\d{2}}", NULL);
    r3_tree_insert_path(n, "/zoo", NULL);
    r3_tree_insert_path(n, "/foo", NULL);
    r3_tree_insert_path(n, "/bar", NULL);

    char *errstr = NULL;
    r3_tree_compile(n, &errstr);

    r3_tree_dump(n, 0);
    node *matched;
    matched = r3_tree_match(n, "/post/11/22", NULL);
    ck_assert((int)matched);
    ck_assert(matched->endpoint > 0);
}
Пример #23
0
Файл: node.c Проект: SciTeX/r3
/**
 * Return the last inserted node.
 */
node * _r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, void * data)
{
    node * n = tree;
    edge * e = NULL;

    /* length of common prefix */
    int prefix_len = 0;
    for( int i = 0 ; i < n->edge_len ; i++ ) {
        prefix_len = strndiff(path, n->edges[i]->pattern, n->edges[i]->pattern_len);

        // printf("prefix_len: %d   %s vs %s\n", prefix_len, path, n->edges[i]->pattern );

        // no common, consider insert a new edge
        if ( prefix_len > 0 ) {
            e = n->edges[i];
            break;
        }
    }

    // branch the edge at correct position (avoid broken slugs)
    char *slug_s;
    if ( (slug_s = inside_slug(path, path_len, path + prefix_len)) != NULL ) {
        prefix_len = slug_s - path;
    }

    // common prefix not found, insert a new edge for this pattern
    if ( prefix_len == 0 ) {
        // there are two more slugs, we should break them into several parts
        if ( count_slug(path, path_len) > 1 ) {
            char *p = find_slug_placeholder(path, NULL);

#ifdef DEBUG
            assert(p);
#endif

            // find the next one
            p = find_slug_placeholder(p + 1, NULL);
#ifdef DEBUG
            assert(p);
#endif

            // insert the first one edge, and break at "p"
            node * child = r3_tree_create(3);
            r3_node_add_child(n, strndup(path, (int)(p - path)), child);

            // and insert the rest part to the child
            return _r3_tree_insert_pathl(child, p, path_len - (int)(p - path),  route, data);
        } else {
            node * child = r3_tree_create(3);
            r3_node_add_child(n, strndup(path, path_len) , child);
            // info("edge not found, insert one: %s\n", path);
            child->data = data;
            child->endpoint++;

            if (route) {
                route->data = data;
                r3_node_append_route(child, route);
            }
            return child;
        }
    } else if ( prefix_len == e->pattern_len ) {    // fully-equal to the pattern of the edge

        char * subpath = path + prefix_len;
        int    subpath_len = path_len - prefix_len;

        // there are something more we can insert
        if ( subpath_len > 0 ) {
            return _r3_tree_insert_pathl(e->child, subpath, subpath_len, route, data);
        } else {
            // there are no more path to insert

            // see if there is an endpoint already
            if (e->child->endpoint) {
                // XXX: return an error code instead of NULL
                return NULL;
            }
            e->child->endpoint++; // make it as an endpoint
            e->child->data = data;
            if (route) {
                route->data = data;
                r3_node_append_route(e->child, route);
            }
            return e->child;
        }

    } else if ( prefix_len < e->pattern_len ) {
        // printf("branch the edge prefix_len: %d\n", prefix_len);


        /* it's partially matched with the pattern,
         * we should split the end point and make a branch here...
         */
        char * s2 = path + prefix_len;
        int   s2_len = path_len - prefix_len;
        r3_edge_branch(e, prefix_len);
        return _r3_tree_insert_pathl(e->child, s2 , s2_len, route , data);
    } else {
        printf("unexpected route.");
        return NULL;
    }
    return n;
}
Пример #24
0
END_TEST



START_TEST(benchmark_str)
{
    match_entry * entry = match_entry_createl("/blog/post", strlen("/blog/post") );
    node * n = r3_tree_create(1);


    int route_data = 999;

r3_tree_insert_path(n, "/foo/bar/baz",  NULL);
r3_tree_insert_path(n, "/foo/bar/qux",  NULL);
r3_tree_insert_path(n, "/foo/bar/quux",  NULL);
r3_tree_insert_path(n, "/foo/bar/corge",  NULL);
r3_tree_insert_path(n, "/foo/bar/grault",  NULL);
r3_tree_insert_path(n, "/foo/bar/garply",  NULL);
r3_tree_insert_path(n, "/foo/baz/bar",  NULL);
r3_tree_insert_path(n, "/foo/baz/qux",  NULL);
r3_tree_insert_path(n, "/foo/baz/quux",  NULL);
r3_tree_insert_path(n, "/foo/baz/corge",  NULL);
r3_tree_insert_path(n, "/foo/baz/grault",  NULL);
r3_tree_insert_path(n, "/foo/baz/garply",  NULL);
r3_tree_insert_path(n, "/foo/qux/bar",  NULL);
r3_tree_insert_path(n, "/foo/qux/baz",  NULL);
r3_tree_insert_path(n, "/foo/qux/quux",  NULL);
r3_tree_insert_path(n, "/foo/qux/corge",  NULL);
r3_tree_insert_path(n, "/foo/qux/grault",  NULL);
r3_tree_insert_path(n, "/foo/qux/garply",  NULL);
r3_tree_insert_path(n, "/foo/quux/bar",  NULL);
r3_tree_insert_path(n, "/foo/quux/baz",  NULL);
r3_tree_insert_path(n, "/foo/quux/qux",  NULL);
r3_tree_insert_path(n, "/foo/quux/corge",  NULL);
r3_tree_insert_path(n, "/foo/quux/grault",  NULL);
r3_tree_insert_path(n, "/foo/quux/garply",  NULL);
r3_tree_insert_path(n, "/foo/corge/bar",  NULL);
r3_tree_insert_path(n, "/foo/corge/baz",  NULL);
r3_tree_insert_path(n, "/foo/corge/qux",  NULL);
r3_tree_insert_path(n, "/foo/corge/quux",  NULL);
r3_tree_insert_path(n, "/foo/corge/grault",  NULL);
r3_tree_insert_path(n, "/foo/corge/garply",  NULL);
r3_tree_insert_path(n, "/foo/grault/bar",  NULL);
r3_tree_insert_path(n, "/foo/grault/baz",  NULL);
r3_tree_insert_path(n, "/foo/grault/qux",  NULL);
r3_tree_insert_path(n, "/foo/grault/quux",  NULL);
r3_tree_insert_path(n, "/foo/grault/corge",  NULL);
r3_tree_insert_path(n, "/foo/grault/garply",  NULL);
r3_tree_insert_path(n, "/foo/garply/bar",  NULL);
r3_tree_insert_path(n, "/foo/garply/baz",  NULL);
r3_tree_insert_path(n, "/foo/garply/qux",  NULL);
r3_tree_insert_path(n, "/foo/garply/quux",  NULL);
r3_tree_insert_path(n, "/foo/garply/corge",  NULL);
r3_tree_insert_path(n, "/foo/garply/grault",  NULL);
r3_tree_insert_path(n, "/bar/foo/baz",  NULL);
r3_tree_insert_path(n, "/bar/foo/qux",  NULL);
r3_tree_insert_path(n, "/bar/foo/quux",  NULL);
r3_tree_insert_path(n, "/bar/foo/corge",  NULL);
r3_tree_insert_path(n, "/bar/foo/grault",  NULL);
r3_tree_insert_path(n, "/bar/foo/garply",  NULL);
r3_tree_insert_path(n, "/bar/baz/foo",  NULL);
r3_tree_insert_path(n, "/bar/baz/qux",  NULL);
r3_tree_insert_path(n, "/bar/baz/quux",  NULL);
r3_tree_insert_path(n, "/bar/baz/corge",  NULL);
r3_tree_insert_path(n, "/bar/baz/grault",  NULL);
r3_tree_insert_path(n, "/bar/baz/garply",  NULL);
r3_tree_insert_path(n, "/bar/qux/foo",  NULL);
r3_tree_insert_path(n, "/bar/qux/baz",  NULL);
r3_tree_insert_path(n, "/bar/qux/quux",  NULL);
r3_tree_insert_path(n, "/bar/qux/corge",  NULL);
r3_tree_insert_path(n, "/bar/qux/grault",  NULL);
r3_tree_insert_path(n, "/bar/qux/garply",  NULL);
r3_tree_insert_path(n, "/bar/quux/foo",  NULL);
r3_tree_insert_path(n, "/bar/quux/baz",  NULL);
r3_tree_insert_path(n, "/bar/quux/qux",  NULL);
r3_tree_insert_path(n, "/bar/quux/corge",  NULL);
r3_tree_insert_path(n, "/bar/quux/grault",  NULL);
r3_tree_insert_path(n, "/bar/quux/garply",  NULL);
r3_tree_insert_path(n, "/bar/corge/foo",  NULL);
r3_tree_insert_path(n, "/bar/corge/baz",  NULL);
r3_tree_insert_path(n, "/bar/corge/qux",  NULL);
r3_tree_insert_path(n, "/bar/corge/quux",  NULL);
r3_tree_insert_path(n, "/bar/corge/grault",  NULL);
r3_tree_insert_path(n, "/bar/corge/garply",  NULL);
r3_tree_insert_path(n, "/bar/grault/foo",  NULL);
r3_tree_insert_path(n, "/bar/grault/baz",  NULL);
r3_tree_insert_path(n, "/bar/grault/qux",  NULL);
r3_tree_insert_path(n, "/bar/grault/quux",  NULL);
r3_tree_insert_path(n, "/bar/grault/corge",  NULL);
r3_tree_insert_path(n, "/bar/grault/garply",  NULL);
r3_tree_insert_path(n, "/bar/garply/foo",  NULL);
r3_tree_insert_path(n, "/bar/garply/baz",  NULL);
r3_tree_insert_path(n, "/bar/garply/qux",  NULL);
r3_tree_insert_path(n, "/bar/garply/quux",  NULL);
r3_tree_insert_path(n, "/bar/garply/corge",  NULL);
r3_tree_insert_path(n, "/bar/garply/grault",  NULL);
r3_tree_insert_path(n, "/baz/foo/bar",  NULL);
r3_tree_insert_path(n, "/baz/foo/qux",  NULL);
r3_tree_insert_path(n, "/baz/foo/quux",  NULL);
r3_tree_insert_path(n, "/baz/foo/corge",  NULL);
r3_tree_insert_path(n, "/baz/foo/grault",  NULL);
r3_tree_insert_path(n, "/baz/foo/garply",  NULL);
r3_tree_insert_path(n, "/baz/bar/foo",  NULL);
r3_tree_insert_path(n, "/baz/bar/qux",  NULL);
r3_tree_insert_path(n, "/baz/bar/quux",  NULL);
r3_tree_insert_path(n, "/baz/bar/corge",  NULL);
r3_tree_insert_path(n, "/baz/bar/grault",  NULL);
r3_tree_insert_path(n, "/baz/bar/garply",  NULL);
r3_tree_insert_path(n, "/baz/qux/foo",  NULL);
r3_tree_insert_path(n, "/baz/qux/bar",  NULL);
r3_tree_insert_path(n, "/baz/qux/quux",  NULL);
r3_tree_insert_path(n, "/baz/qux/corge",  NULL);
r3_tree_insert_path(n, "/baz/qux/grault",  NULL);
r3_tree_insert_path(n, "/baz/qux/garply",  NULL);
r3_tree_insert_path(n, "/baz/quux/foo",  NULL);
r3_tree_insert_path(n, "/baz/quux/bar",  NULL);
r3_tree_insert_path(n, "/baz/quux/qux",  NULL);
r3_tree_insert_path(n, "/baz/quux/corge",  NULL);
r3_tree_insert_path(n, "/baz/quux/grault",  NULL);
r3_tree_insert_path(n, "/baz/quux/garply",  NULL);
r3_tree_insert_path(n, "/baz/corge/foo",  NULL);
r3_tree_insert_path(n, "/baz/corge/bar",  NULL);
r3_tree_insert_path(n, "/baz/corge/qux",  NULL);
r3_tree_insert_path(n, "/baz/corge/quux",  NULL);
r3_tree_insert_path(n, "/baz/corge/grault",  NULL);
r3_tree_insert_path(n, "/baz/corge/garply",  NULL);
r3_tree_insert_path(n, "/baz/grault/foo",  NULL);
r3_tree_insert_path(n, "/baz/grault/bar",  NULL);
r3_tree_insert_path(n, "/baz/grault/qux",  NULL);
r3_tree_insert_path(n, "/baz/grault/quux",  NULL);
r3_tree_insert_path(n, "/baz/grault/corge",  NULL);
r3_tree_insert_path(n, "/baz/grault/garply",  NULL);
r3_tree_insert_path(n, "/baz/garply/foo",  NULL);
r3_tree_insert_path(n, "/baz/garply/bar",  NULL);
r3_tree_insert_path(n, "/baz/garply/qux",  NULL);
r3_tree_insert_path(n, "/baz/garply/quux",  NULL);
r3_tree_insert_path(n, "/baz/garply/corge",  NULL);
r3_tree_insert_path(n, "/baz/garply/grault",  NULL);
r3_tree_insert_path(n, "/qux/foo/bar",  NULL);
r3_tree_insert_path(n, "/qux/foo/baz",  NULL);
r3_tree_insert_path(n, "/qux/foo/quux",  NULL);
r3_tree_insert_path(n, "/qux/foo/corge",  NULL);
r3_tree_insert_path(n, "/qux/foo/grault",  NULL);
r3_tree_insert_path(n, "/qux/foo/garply",  NULL);
r3_tree_insert_path(n, "/qux/bar/foo",  NULL);
r3_tree_insert_path(n, "/qux/bar/baz",  NULL);
r3_tree_insert_path(n, "/qux/bar/quux",  NULL);
r3_tree_insert_path(n, "/qux/bar/corge",  &route_data);
r3_tree_insert_path(n, "/qux/bar/grault",  NULL);
r3_tree_insert_path(n, "/qux/bar/garply",  NULL);
r3_tree_insert_path(n, "/qux/baz/foo",  NULL);
r3_tree_insert_path(n, "/qux/baz/bar",  NULL);
r3_tree_insert_path(n, "/qux/baz/quux",  NULL);
r3_tree_insert_path(n, "/qux/baz/corge",  NULL);
r3_tree_insert_path(n, "/qux/baz/grault",  NULL);
r3_tree_insert_path(n, "/qux/baz/garply",  NULL);
r3_tree_insert_path(n, "/qux/quux/foo",  NULL);
r3_tree_insert_path(n, "/qux/quux/bar",  NULL);
r3_tree_insert_path(n, "/qux/quux/baz",  NULL);
r3_tree_insert_path(n, "/qux/quux/corge",  NULL);
r3_tree_insert_path(n, "/qux/quux/grault",  NULL);
r3_tree_insert_path(n, "/qux/quux/garply",  NULL);
r3_tree_insert_path(n, "/qux/corge/foo",  NULL);
r3_tree_insert_path(n, "/qux/corge/bar",  NULL);
r3_tree_insert_path(n, "/qux/corge/baz",  NULL);
r3_tree_insert_path(n, "/qux/corge/quux",  NULL);
r3_tree_insert_path(n, "/qux/corge/grault",  NULL);
r3_tree_insert_path(n, "/qux/corge/garply",  NULL);
r3_tree_insert_path(n, "/qux/grault/foo",  NULL);
r3_tree_insert_path(n, "/qux/grault/bar",  NULL);
r3_tree_insert_path(n, "/qux/grault/baz",  NULL);
r3_tree_insert_path(n, "/qux/grault/quux",  NULL);
r3_tree_insert_path(n, "/qux/grault/corge",  NULL);
r3_tree_insert_path(n, "/qux/grault/garply",  NULL);
r3_tree_insert_path(n, "/qux/garply/foo",  NULL);
r3_tree_insert_path(n, "/qux/garply/bar",  NULL);
r3_tree_insert_path(n, "/qux/garply/baz",  NULL);
r3_tree_insert_path(n, "/qux/garply/quux",  NULL);
r3_tree_insert_path(n, "/qux/garply/corge",  NULL);
r3_tree_insert_path(n, "/qux/garply/grault",  NULL);
r3_tree_insert_path(n, "/quux/foo/bar",  NULL);
r3_tree_insert_path(n, "/quux/foo/baz",  NULL);
r3_tree_insert_path(n, "/quux/foo/qux",  NULL);
r3_tree_insert_path(n, "/quux/foo/corge",  NULL);
r3_tree_insert_path(n, "/quux/foo/grault",  NULL);
r3_tree_insert_path(n, "/quux/foo/garply",  NULL);
r3_tree_insert_path(n, "/quux/bar/foo",  NULL);
r3_tree_insert_path(n, "/quux/bar/baz",  NULL);
r3_tree_insert_path(n, "/quux/bar/qux",  NULL);
r3_tree_insert_path(n, "/quux/bar/corge",  NULL);
r3_tree_insert_path(n, "/quux/bar/grault",  NULL);
r3_tree_insert_path(n, "/quux/bar/garply",  NULL);
r3_tree_insert_path(n, "/quux/baz/foo",  NULL);
r3_tree_insert_path(n, "/quux/baz/bar",  NULL);
r3_tree_insert_path(n, "/quux/baz/qux",  NULL);
r3_tree_insert_path(n, "/quux/baz/corge",  NULL);
r3_tree_insert_path(n, "/quux/baz/grault",  NULL);
r3_tree_insert_path(n, "/quux/baz/garply",  NULL);
r3_tree_insert_path(n, "/quux/qux/foo",  NULL);
r3_tree_insert_path(n, "/quux/qux/bar",  NULL);
r3_tree_insert_path(n, "/quux/qux/baz",  NULL);
r3_tree_insert_path(n, "/quux/qux/corge",  NULL);
r3_tree_insert_path(n, "/quux/qux/grault",  NULL);
r3_tree_insert_path(n, "/quux/qux/garply",  NULL);
r3_tree_insert_path(n, "/quux/corge/foo",  NULL);
r3_tree_insert_path(n, "/quux/corge/bar",  NULL);
r3_tree_insert_path(n, "/quux/corge/baz",  NULL);
r3_tree_insert_path(n, "/quux/corge/qux",  NULL);
r3_tree_insert_path(n, "/quux/corge/grault",  NULL);
r3_tree_insert_path(n, "/quux/corge/garply",  NULL);
r3_tree_insert_path(n, "/quux/grault/foo",  NULL);
r3_tree_insert_path(n, "/quux/grault/bar",  NULL);
r3_tree_insert_path(n, "/quux/grault/baz",  NULL);
r3_tree_insert_path(n, "/quux/grault/qux",  NULL);
r3_tree_insert_path(n, "/quux/grault/corge",  NULL);
r3_tree_insert_path(n, "/quux/grault/garply",  NULL);
r3_tree_insert_path(n, "/quux/garply/foo",  NULL);
r3_tree_insert_path(n, "/quux/garply/bar",  NULL);
r3_tree_insert_path(n, "/quux/garply/baz",  NULL);
r3_tree_insert_path(n, "/quux/garply/qux",  NULL);
r3_tree_insert_path(n, "/quux/garply/corge",  NULL);
r3_tree_insert_path(n, "/quux/garply/grault",  NULL);
r3_tree_insert_path(n, "/corge/foo/bar",  NULL);
r3_tree_insert_path(n, "/corge/foo/baz",  NULL);
r3_tree_insert_path(n, "/corge/foo/qux",  NULL);
r3_tree_insert_path(n, "/corge/foo/quux",  NULL);
r3_tree_insert_path(n, "/corge/foo/grault",  NULL);
r3_tree_insert_path(n, "/corge/foo/garply",  NULL);
r3_tree_insert_path(n, "/corge/bar/foo",  NULL);
r3_tree_insert_path(n, "/corge/bar/baz",  NULL);
r3_tree_insert_path(n, "/corge/bar/qux",  NULL);
r3_tree_insert_path(n, "/corge/bar/quux",  NULL);
r3_tree_insert_path(n, "/corge/bar/grault",  NULL);
r3_tree_insert_path(n, "/corge/bar/garply",  NULL);
r3_tree_insert_path(n, "/corge/baz/foo",  NULL);
r3_tree_insert_path(n, "/corge/baz/bar",  NULL);
r3_tree_insert_path(n, "/corge/baz/qux",  NULL);
r3_tree_insert_path(n, "/corge/baz/quux",  NULL);
r3_tree_insert_path(n, "/corge/baz/grault",  NULL);
r3_tree_insert_path(n, "/corge/baz/garply",  NULL);
r3_tree_insert_path(n, "/corge/qux/foo",  NULL);
r3_tree_insert_path(n, "/corge/qux/bar",  NULL);
r3_tree_insert_path(n, "/corge/qux/baz",  NULL);
r3_tree_insert_path(n, "/corge/qux/quux",  NULL);
r3_tree_insert_path(n, "/corge/qux/grault",  NULL);
r3_tree_insert_path(n, "/corge/qux/garply",  NULL);
r3_tree_insert_path(n, "/corge/quux/foo",  NULL);
r3_tree_insert_path(n, "/corge/quux/bar",  NULL);
r3_tree_insert_path(n, "/corge/quux/baz",  NULL);
r3_tree_insert_path(n, "/corge/quux/qux",  NULL);
r3_tree_insert_path(n, "/corge/quux/grault",  NULL);
r3_tree_insert_path(n, "/corge/quux/garply",  NULL);
r3_tree_insert_path(n, "/corge/grault/foo",  NULL);
r3_tree_insert_path(n, "/corge/grault/bar",  NULL);
r3_tree_insert_path(n, "/corge/grault/baz",  NULL);
r3_tree_insert_path(n, "/corge/grault/qux",  NULL);
r3_tree_insert_path(n, "/corge/grault/quux",  NULL);
r3_tree_insert_path(n, "/corge/grault/garply",  NULL);
r3_tree_insert_path(n, "/corge/garply/foo",  NULL);
r3_tree_insert_path(n, "/corge/garply/bar",  NULL);
r3_tree_insert_path(n, "/corge/garply/baz",  NULL);
r3_tree_insert_path(n, "/corge/garply/qux",  NULL);
r3_tree_insert_path(n, "/corge/garply/quux",  NULL);
r3_tree_insert_path(n, "/corge/garply/grault",  NULL);
r3_tree_insert_path(n, "/grault/foo/bar",  NULL);
r3_tree_insert_path(n, "/grault/foo/baz",  NULL);
r3_tree_insert_path(n, "/grault/foo/qux",  NULL);
r3_tree_insert_path(n, "/grault/foo/quux",  NULL);
r3_tree_insert_path(n, "/grault/foo/corge",  NULL);
r3_tree_insert_path(n, "/grault/foo/garply",  NULL);
r3_tree_insert_path(n, "/grault/bar/foo",  NULL);
r3_tree_insert_path(n, "/grault/bar/baz",  NULL);
r3_tree_insert_path(n, "/grault/bar/qux",  NULL);
r3_tree_insert_path(n, "/grault/bar/quux",  NULL);
r3_tree_insert_path(n, "/grault/bar/corge",  NULL);
r3_tree_insert_path(n, "/grault/bar/garply",  NULL);
r3_tree_insert_path(n, "/grault/baz/foo",  NULL);
r3_tree_insert_path(n, "/grault/baz/bar",  NULL);
r3_tree_insert_path(n, "/grault/baz/qux",  NULL);
r3_tree_insert_path(n, "/grault/baz/quux",  NULL);
r3_tree_insert_path(n, "/grault/baz/corge",  NULL);
r3_tree_insert_path(n, "/grault/baz/garply",  NULL);
r3_tree_insert_path(n, "/grault/qux/foo",  NULL);
r3_tree_insert_path(n, "/grault/qux/bar",  NULL);
r3_tree_insert_path(n, "/grault/qux/baz",  NULL);
r3_tree_insert_path(n, "/grault/qux/quux",  NULL);
r3_tree_insert_path(n, "/grault/qux/corge",  NULL);
r3_tree_insert_path(n, "/grault/qux/garply",  NULL);
r3_tree_insert_path(n, "/grault/quux/foo",  NULL);
r3_tree_insert_path(n, "/grault/quux/bar",  NULL);
r3_tree_insert_path(n, "/grault/quux/baz",  NULL);
r3_tree_insert_path(n, "/grault/quux/qux",  NULL);
r3_tree_insert_path(n, "/grault/quux/corge",  NULL);
r3_tree_insert_path(n, "/grault/quux/garply",  NULL);
r3_tree_insert_path(n, "/grault/corge/foo",  NULL);
r3_tree_insert_path(n, "/grault/corge/bar",  NULL);
r3_tree_insert_path(n, "/grault/corge/baz",  NULL);
r3_tree_insert_path(n, "/grault/corge/qux",  NULL);
r3_tree_insert_path(n, "/grault/corge/quux",  NULL);
r3_tree_insert_path(n, "/grault/corge/garply",  NULL);
r3_tree_insert_path(n, "/grault/garply/foo",  NULL);
r3_tree_insert_path(n, "/grault/garply/bar",  NULL);
r3_tree_insert_path(n, "/grault/garply/baz",  NULL);
r3_tree_insert_path(n, "/grault/garply/qux",  NULL);
r3_tree_insert_path(n, "/grault/garply/quux",  NULL);
r3_tree_insert_path(n, "/grault/garply/corge",  NULL);
r3_tree_insert_path(n, "/garply/foo/bar",  NULL);
r3_tree_insert_path(n, "/garply/foo/baz",  NULL);
r3_tree_insert_path(n, "/garply/foo/qux",  NULL);
r3_tree_insert_path(n, "/garply/foo/quux",  NULL);
r3_tree_insert_path(n, "/garply/foo/corge",  NULL);
r3_tree_insert_path(n, "/garply/foo/grault",  NULL);
r3_tree_insert_path(n, "/garply/bar/foo",  NULL);
r3_tree_insert_path(n, "/garply/bar/baz",  NULL);
r3_tree_insert_path(n, "/garply/bar/qux",  NULL);
r3_tree_insert_path(n, "/garply/bar/quux",  NULL);
r3_tree_insert_path(n, "/garply/bar/corge",  NULL);
r3_tree_insert_path(n, "/garply/bar/grault",  NULL);
r3_tree_insert_path(n, "/garply/baz/foo",  NULL);
r3_tree_insert_path(n, "/garply/baz/bar",  NULL);
r3_tree_insert_path(n, "/garply/baz/qux",  NULL);
r3_tree_insert_path(n, "/garply/baz/quux",  NULL);
r3_tree_insert_path(n, "/garply/baz/corge",  NULL);
r3_tree_insert_path(n, "/garply/baz/grault",  NULL);
r3_tree_insert_path(n, "/garply/qux/foo",  NULL);
r3_tree_insert_path(n, "/garply/qux/bar",  NULL);
r3_tree_insert_path(n, "/garply/qux/baz",  NULL);
r3_tree_insert_path(n, "/garply/qux/quux",  NULL);
r3_tree_insert_path(n, "/garply/qux/corge",  NULL);
r3_tree_insert_path(n, "/garply/qux/grault",  NULL);
r3_tree_insert_path(n, "/garply/quux/foo",  NULL);
r3_tree_insert_path(n, "/garply/quux/bar",  NULL);
r3_tree_insert_path(n, "/garply/quux/baz",  NULL);
r3_tree_insert_path(n, "/garply/quux/qux",  NULL);
r3_tree_insert_path(n, "/garply/quux/corge",  NULL);
r3_tree_insert_path(n, "/garply/quux/grault",  NULL);
r3_tree_insert_path(n, "/garply/corge/foo",  NULL);
r3_tree_insert_path(n, "/garply/corge/bar",  NULL);
r3_tree_insert_path(n, "/garply/corge/baz",  NULL);
r3_tree_insert_path(n, "/garply/corge/qux",  NULL);
r3_tree_insert_path(n, "/garply/corge/quux",  NULL);
r3_tree_insert_path(n, "/garply/corge/grault",  NULL);
r3_tree_insert_path(n, "/garply/grault/foo",  NULL);
r3_tree_insert_path(n, "/garply/grault/bar",  NULL);
r3_tree_insert_path(n, "/garply/grault/baz",  NULL);
r3_tree_insert_path(n, "/garply/grault/qux",  NULL);
r3_tree_insert_path(n, "/garply/grault/quux",  NULL);
r3_tree_insert_path(n, "/garply/grault/corge",  NULL);


    r3_tree_compile(n);
    // r3_tree_dump(n, 0);
    // match_entry *entry = calloc( sizeof(entry) , 1 );

    node *m;
    m = r3_tree_match(n , "/qux/bar/corge", NULL);
    fail_if( m == NULL );
    // r3_tree_dump( m, 0 );
    ck_assert_int_eq( *((int*) m->data), 999 );


    printf("Benchmarking...\n");
    BENCHMARK(string_dispatch)
    r3_tree_matchl(n , "/qux/bar/corge", strlen("/qux/bar/corge"), NULL);
    END_BENCHMARK()

    bench_print_summary(&B);

    FILE *fp = fopen("bench_str.csv", "a+");
    fprintf(fp, "%ld,%.2f\n", unixtime(), (B.N * B.R) / (B.end - B.start));
    fclose(fp);

}
Пример #25
0
END_TEST


START_TEST (test_compile)
{
    str_array *t;
    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("/") ) );

#ifdef DEBUG
    r3_tree_dump(n, 0);
#endif

    r3_tree_insert_path(n, "/foo/{id}", NULL);
    r3_tree_insert_path(n, "/{id}", NULL);
    r3_tree_compile(n);
    r3_tree_compile(n); // test double compile
#ifdef DEBUG
    r3_tree_dump(n, 0);
#endif
    /*
    fail_if(n->edges[0]->child->combined_pattern == NULL);

    e = r3_node_find_edge_str(n, "/", strlen("/") );
    fail_if( NULL == e );
    */
    /*
    printf( "%s\n", e->pattern );
    printf( "%s\n", e->child->combined_pattern );
    printf( "%s\n", n->edges[0]->child->combined_pattern);
    printf( "%s\n", n->combined_pattern );
    */

    match_entry * entry;

    entry = match_entry_createl( "foo" , strlen("/foo") );
    m = r3_tree_matchl( n , "/foo", strlen("/foo"), entry);
    fail_if( NULL == m );

    entry = match_entry_createl( "/zoo" , strlen("/zoo") );
    m = r3_tree_matchl( n , "/zoo", strlen("/zoo"), entry);
    fail_if( NULL == m );

    entry = match_entry_createl( "/bar" , strlen("/bar") );
    m = r3_tree_matchl( n , "/bar", strlen("/bar"), entry);
    fail_if( NULL == m );

    entry = match_entry_createl( "/xxx" , strlen("/xxx") );
    m = r3_tree_matchl( n , "/xxx", strlen("/xxx"), entry);
    fail_if( NULL == m );

    entry = match_entry_createl( "/foo/xxx" , strlen("/foo/xxx") );
    m = r3_tree_matchl( n , "/foo/xxx", strlen("/foo/xxx"), entry);
    fail_if( NULL == m );

    entry = match_entry_createl( "/some_id" , strlen("/some_id") );
    m = r3_tree_matchl( n , "/some_id", strlen("/some_id"), entry);
    fail_if( NULL == m );
    ck_assert_int_gt( m->endpoint , 0 ); // should not be an endpoint
}
Пример #26
0
Файл: node.c Проект: RickySu/r3
/**
 * Return the last inserted node.
 */
node * r3_tree_insert_pathl_ex(node *tree, const char *path, int path_len, route * route, void * data, char **errstr)
{
    node * n = tree;

    // common edge
    edge * e = NULL;

    // If there is no path to insert at the node, we just increase the mount
    // point on the node and append the route.
    if (path_len == 0) {
        tree->endpoint++;
        if (route) {
            route->data = data;
            r3_node_append_route(tree, route);
        }
        return tree;
    }

    /* length of common prefix */
    int prefix_len = 0;
    char *err = NULL;
    e = r3_node_find_common_prefix(tree, path, path_len, &prefix_len, &err);
    if (err) {
        // copy the error message pointer
        if (errstr) *errstr = err;
        return NULL;
    }

    const char * subpath = path + prefix_len;
    const int    subpath_len = path_len - prefix_len;

    // common prefix not found, insert a new edge for this pattern
    if ( prefix_len == 0 ) {
        // there are two more slugs, we should break them into several parts
        int slug_cnt = r3_slug_count(path, path_len, errstr);
        if (slug_cnt == -1) {
            return NULL;
        }

        if ( slug_cnt > 1 ) {
            int   slug_len;
            char *p = r3_slug_find_placeholder(path, &slug_len);

#ifdef DEBUG
            assert(p);
#endif

            // find the next one '{', then break there
            if(p) {
                p = r3_slug_find_placeholder(p + slug_len + 1, NULL);
            }
#ifdef DEBUG
            assert(p);
#endif

            // insert the first one edge, and break at "p"
            node * child = r3_tree_create(3);
            CHECK_PTR(child);

            r3_node_connect(n, zstrndup(path, (int)(p - path)), child);

            // and insert the rest part to the child
            return r3_tree_insert_pathl_ex(child, p, path_len - (int)(p - path),  route, data, errstr);

        } else {
            if (slug_cnt == 1) {
                // there is one slug, let's see if it's optimiz-able by opcode
                int   slug_len = 0;
                char *slug_p = r3_slug_find_placeholder(path, &slug_len);
                int   slug_pattern_len = 0;
                char *slug_pattern = r3_slug_find_pattern(slug_p, &slug_pattern_len);

                int opcode = 0;
                // if there is a pattern defined.
                if (slug_pattern_len) {
                    char *cpattern = r3_slug_compile(slug_pattern, slug_pattern_len);
                    opcode = r3_pattern_to_opcode(cpattern, strlen(cpattern));
                    zfree(cpattern);
                } else {
                    opcode = OP_EXPECT_NOSLASH;
                }


                // if the slug starts after one+ charactor, for example foo{slug}
                node *c1;
                if (slug_p > path) {
                    c1 = r3_tree_create(3);
                    CHECK_PTR(c1);
                    r3_node_connectl(n, path, slug_p - path, 1, c1); // duplicate
                } else {
                    c1 = n;
                }

                node * c2 = r3_tree_create(3);
                CHECK_PTR(c2);

                edge * op_edge = r3_node_connectl(c1, slug_p, slug_len , 1, c2);
                if(opcode) {
                    op_edge->opcode = opcode;
                }

                int restlen = path_len - ((slug_p - path) + slug_len);

                if (restlen) {
                    return r3_tree_insert_pathl_ex(c2, slug_p + slug_len, restlen, route, data, errstr);
                }

                c2->data = data;
                c2->endpoint++;
                if (route) {
                    route->data = data;
                    r3_node_append_route(c2, route);
                }
                return c2;
            }
            // only one slug
            node * child = r3_tree_create(3);
            CHECK_PTR(child);
            child->endpoint++;
            if (data)
                child->data = data;

            r3_node_connectl(n, path, path_len, 1, child);
            if (route) {
                route->data = data;
                r3_node_append_route(child, route);
            }
            return child;
        }
    } else if ( prefix_len == e->pattern_len ) {    // fully-equal to the pattern of the edge

        // there are something more we can insert
        if ( subpath_len > 0 ) {
            return r3_tree_insert_pathl_ex(e->child, subpath, subpath_len, route, data, errstr);
        } else {
            // there are no more path to insert

            // see if there is an endpoint already, we should n't overwrite the data on child.
            // but we still need to append the route.

            if (route) {
                route->data = data;
                r3_node_append_route(e->child, route);
                e->child->endpoint++; // make it as an endpoint
                return e->child;
            }

            // insertion without route
            if (e->child->endpoint > 0) {
                // TODO: return an error code instead of NULL
                return NULL;
            }
            e->child->endpoint++; // make it as an endpoint
            e->child->data = data; // set data
            return e->child;
        }

    } else if ( prefix_len < e->pattern_len ) {
        /* it's partially matched with the pattern,
         * we should split the end point and make a branch here...
         */
        r3_edge_branch(e, prefix_len);
        return r3_tree_insert_pathl_ex(e->child, subpath, subpath_len, route , data, errstr);
    } else {
        fprintf(stderr, "unexpected route.");
        return NULL;
    }
    return n;
}
Пример #27
0
Файл: node.c Проект: lucemia/r3
/**
 * Return the last inserted node.
 */
node * r3_tree_insert_pathl_(node *tree, char *path, int path_len, route * route, void * data)
{
    node * n = tree;
    edge * e = NULL;

    /* length of common prefix */
    int prefix_len = 0;
    for( int i = 0 ; i < n->edge_len ; i++ ) {
        prefix_len = strndiff(path, n->edges[i]->pattern, n->edges[i]->pattern_len);

        // printf("prefix_len: %d   %s vs %s\n", prefix_len, path, n->edges[i]->pattern );

        // no common, consider insert a new edge
        if ( prefix_len > 0 ) {
            e = n->edges[i];
            break;
        }
    }

    // branch the edge at correct position (avoid broken slugs)
    char *slug_s;
    if ( (slug_s = inside_slug(path, path_len, path + prefix_len)) != NULL ) {
        prefix_len = slug_s - path;
    }

    // common prefix not found, insert a new edge for this pattern
    if ( prefix_len == 0 ) {
        // there are two more slugs, we should break them into several parts
        int slug_cnt = slug_count(path, path_len);
        if ( slug_cnt > 1 ) {
            int   slug_len;
            char *p = slug_find_placeholder(path, &slug_len);

#ifdef DEBUG
            assert(p);
#endif

            // find the next one '{', then break there
            if(p) {
                p = slug_find_placeholder(p + slug_len + 1, NULL);
            }
#ifdef DEBUG
            assert(p);
#endif

            // insert the first one edge, and break at "p"
            node * child = r3_tree_create(3);
            r3_node_connect(n, zstrndup(path, (int)(p - path)), child);

            // and insert the rest part to the child
            return r3_tree_insert_pathl_(child, p, path_len - (int)(p - path),  route, data);

        } else {
            if (slug_cnt == 1) {
                // there is one slug, let's see if it's optimiz-able by opcode
                int   slug_len = 0;
                char *slug_p = slug_find_placeholder(path, &slug_len);
                int   slug_pattern_len = 0;
                char *slug_pattern = slug_find_pattern(slug_p, &slug_pattern_len);
                int opcode = 0;
                // if there is a pattern defined.
                if (slug_pattern) {
                    char *cpattern = slug_compile(slug_pattern, slug_pattern_len);
                    opcode = r3_pattern_to_opcode(cpattern, strlen(cpattern));
                    zfree(cpattern);
                } else {
                    opcode = OP_EXPECT_NOSLASH;
                }
                // found opcode
                if (opcode) {
                    // if the slug starts after one+ charactor, for example foo{slug}
                    node *c1;
                    if (slug_p > path) {
                        c1 = r3_tree_create(3);
                        r3_node_connectl(n, path, slug_p - path, 1, c1); // duplicate
                    } else {
                        c1 = n;
                    }

                    node * c2 = r3_tree_create(3);
                    edge * op_edge = r3_node_connectl(c1, slug_p, slug_len , 1, c2);
                    op_edge->opcode = opcode;

                    // insert rest
                    int restlen = (path_len - (slug_p - path)) - slug_len;
                    if (restlen) {
                        return r3_tree_insert_pathl_(c2, slug_p + slug_len, restlen, route, data);
                    }

                    c2->data = data;
                    c2->endpoint++;
                    if (route) {
                        route->data = data;
                        r3_node_append_route(c2, route);
                    }
                    return c2;
                }
            }
            // only one slug
            node * child = r3_tree_create(3);
            r3_node_connect(n, zstrndup(path, path_len) , child);
            child->data = data;
            child->endpoint++;
            if (route) {
                route->data = data;
                r3_node_append_route(child, route);
            }
            return child;
        }
    } else if ( prefix_len == e->pattern_len ) {    // fully-equal to the pattern of the edge

        char * subpath = path + prefix_len;
        int    subpath_len = path_len - prefix_len;

        // there are something more we can insert
        if ( subpath_len > 0 ) {
            return r3_tree_insert_pathl_(e->child, subpath, subpath_len, route, data);
        } else {
            // there are no more path to insert

            // see if there is an endpoint already
            if (e->child->endpoint > 0) {
                // XXX: return an error code instead of NULL
                return NULL;
            }
            e->child->endpoint++; // make it as an endpoint
            e->child->data = data;
            if (route) {
                route->data = data;
                r3_node_append_route(e->child, route);
            }
            return e->child;
        }

    } else if ( prefix_len < e->pattern_len ) {
        /* it's partially matched with the pattern,
         * we should split the end point and make a branch here...
         */
        char * s2 = path + prefix_len;
        int   s2_len = path_len - prefix_len;
        r3_edge_branch(e, prefix_len);
        return r3_tree_insert_pathl_(e->child, s2 , s2_len, route , data);
    } else {
        printf("unexpected route.");
        return NULL;
    }
    return n;
}
Пример #28
0
/**
 * Return the last inserted node.
 */
node * r3_tree_insert_pathl(node *tree, char *path, int path_len, route * route, void * data)
{
    node * n = tree;
    edge * e = NULL;

    /* length of common prefix */
    int offset = 0;
    for( int i = 0 ; i < n->edge_len ; i++ ) {
        offset = strndiff(path, n->edges[i]->pattern, n->edges[i]->pattern_len);

        // printf("offset: %d   %s vs %s\n", offset, path, n->edges[i]->pattern );

        // no common, consider insert a new edge
        if ( offset > 0 ) {
            e = n->edges[i];
            break;
        }
    }

    // branch the edge at correct position (avoid broken slugs)
    char *slug_s = strchr(path, '{');
    char *slug_e = strchr(path, '}');
    if ( slug_s && slug_e ) {
        if ( offset > (slug_s - path) && offset < (slug_e - path) ) {
            // break before '{'
            offset = slug_s - path;
        }
    }

    if ( offset == 0 ) {
        // not found, we should just insert a whole new edge
        node * child = r3_tree_create(3);
        r3_node_add_child(n, strndup(path, path_len) , child);
        info("edge not found, insert one: %s\n", path);
        child->data = data;
        child->endpoint++;

        if (route) {
            route->data = data;
            r3_node_append_route(child, route);
        }
        return child;
    } else if ( offset == e->pattern_len ) {    // fully-equal to the pattern of the edge

        char * subpath = path + offset;
        int    subpath_len = path_len - offset;

        // there are something more we can insert
        if ( subpath_len > 0 ) {
            return r3_tree_insert_pathl(e->child, subpath, subpath_len, route, data);
        } else {
            // no more path to insert
            e->child->endpoint++; // make it as an endpoint
            e->child->data = data;
            if (route) {
                route->data = data;
                r3_node_append_route(e->child, route);
            }
            return e->child;
        }

    } else if ( offset < e->pattern_len ) {
        // printf("branch the edge offset: %d\n", offset);


        /* it's partially matched with the pattern,
         * we should split the end point and make a branch here...
         */
        node *c2; // child 1, child 2
        edge *e2; // edge 1, edge 2
        char * s2 = path + offset;
        int s2_len = 0;

        r3_edge_branch(e, offset);

        // here is the new edge from.
        c2 = r3_tree_create(3);
        s2_len = path_len - offset;
        e2 = r3_edge_create(strndup(s2, s2_len), s2_len, c2);
        // printf("edge right: %s\n", e2->pattern);
        r3_node_append_edge(e->child, e2);


        char *op = e->pattern;
        // truncate the original edge pattern 
        e->pattern = strndup(e->pattern, offset);
        e->pattern_len = offset;
        free(op);

        // move n->edges to c1
        c2->endpoint++;
        c2->data = data;

        if (route) {
            route->data = data;
            r3_node_append_route(c2, route);
        }
        return c2;
    } else {
        printf("unexpected route.");
        return NULL;
    }
    return n;
}