/* * edge.c * Copyright (C) 2014 c9s * * Distributed under terms of the MIT license. */ #include "config.h" #include #include #include #include // Jemalloc memory management // #include // PCRE #include #include "r3.h" #include "r3_str.h" #include "slug.h" #include "zmalloc.h" #define CHECK_PTR(ptr) if (ptr == NULL) return NULL; 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; e->child = child; e->has_slug = r3_path_contains_slug_char(e->pattern); return e; } /** * 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) * */ node * r3_edge_branch(edge *e, int dl) { node * new_child; edge * new_edge; // the rest string char * s1 = e->pattern + dl; int s1_len = e->pattern_len - dl; // the suffix edge of the leaf new_child = r3_tree_create(3); new_edge = r3_edge_createl(zstrndup(s1, s1_len), s1_len, new_child); // Move child node to the new edge new_edge->child = e->child; e->child = new_child; r3_node_append_edge(new_child, new_edge); // truncate the original edge pattern char *oldpattern = e->pattern; e->pattern = zstrndup(e->pattern, dl); e->pattern_len = dl; zfree(oldpattern); return new_child; } void r3_edge_free(edge * e) { zfree(e->pattern); if ( e->child ) { r3_tree_free(e->child); } // free itself zfree(e); }