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); }
/** * Connect two node objects, and create an edge object between them. */ edge * r3_node_connectl(node * n, const char * pat, int len, int dupl, node *child) { // find the same sub-pattern, if it does not exist, create one edge * e; e = r3_node_find_edge(n, pat, len); if (e) { return e; } if (dupl) { pat = zstrndup(pat, len); } e = r3_edge_createl(pat, len, child); CHECK_PTR(e); r3_node_append_edge(n, e); return e; }
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); }
/** * 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; // the suffix edge of the leaf new_child = r3_tree_create(3); s1_len = e->pattern_len - 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; } e->child->edge_len = 0; // Migrate the child routes for ( int i = 0 ; i < e->child->route_len ; i++ ) { r3_node_append_route(new_child, e->child->routes[i]); e->child->routes[i] = NULL; } e->child->route_len = 0; // Migrate the endpoint new_child->endpoint = e->child->endpoint; e->child->endpoint = 0; // reset endpoint // Migrate the data new_child->data = e->child->data; // copy data pointer e->child->data = NULL; r3_node_append_edge(e->child, e1); // truncate the original edge pattern char *oldpattern = e->pattern; e->pattern = zstrndup(e->pattern, dl); e->pattern_len = dl; zfree(oldpattern); return new_child; }