r3/src/edge.c

108 lines
2.3 KiB
C
Raw Normal View History

2014-05-16 08:38:14 -04:00
/*
* edge.c
2014-06-27 01:24:40 -04:00
* Copyright (C) 2014 c9s <yoanlin93@gmail.com>
2014-05-16 08:38:14 -04:00
*
* Distributed under terms of the MIT license.
*/
2014-06-03 09:47:52 -04:00
#include "config.h"
2014-05-16 08:38:14 -04:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
// Jemalloc memory management
2014-05-19 13:28:51 -04:00
// #include <jemalloc/jemalloc.h>
2014-05-16 08:38:14 -04:00
// PCRE
#include <pcre.h>
// Judy array
2014-05-16 10:05:23 -04:00
// #include <Judy.h>
2014-05-16 08:38:14 -04:00
#include "r3.h"
2014-05-20 11:33:51 -04:00
#include "r3_str.h"
2014-06-01 20:04:57 -04:00
#include "slug.h"
2014-05-21 02:59:07 -04:00
#include "zmalloc.h"
2014-05-16 08:38:14 -04:00
2014-06-04 11:13:08 -04:00
#define CHECK_PTR(ptr) if (ptr == NULL) return NULL;
2014-06-01 21:48:00 -04:00
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child) {
edge * e = (edge*) zmalloc( sizeof(edge) );
2014-06-04 11:13:08 -04:00
CHECK_PTR(e);
2014-05-26 13:08:31 -04:00
e->pattern = (char*) pattern;
2014-05-18 00:24:07 -04:00
e->pattern_len = pattern_len;
2014-05-22 23:47:44 -04:00
e->opcode = 0;
2014-05-18 00:24:07 -04:00
e->child = child;
2014-06-01 20:04:57 -04:00
e->has_slug = r3_path_contains_slug_char(e->pattern);
2014-05-18 00:24:07 -04:00
return e;
}
2014-05-16 08:38:14 -04:00
/**
* branch the edge pattern at "dl" offset,
* insert a dummy child between the edges.
*
2014-05-18 07:09:47 -04:00
*
* A -> [prefix..suffix] -> B
* A -> [prefix] -> B -> [suffix] -> New Child (Copy Data, Edges from B)
2014-05-16 08:38:14 -04:00
*
*/
2014-05-18 07:09:47 -04:00
node * r3_edge_branch(edge *e, int dl) {
node *new_child;
edge *e1;
2014-05-16 08:38:14 -04:00
char * s1 = e->pattern + dl;
int s1_len = 0;
// the suffix edge of the leaf
2014-05-18 07:09:47 -04:00
new_child = r3_tree_create(3);
2014-05-16 08:38:14 -04:00
s1_len = e->pattern_len - dl;
2014-06-01 21:48:00 -04:00
e1 = r3_edge_createl(zstrndup(s1, s1_len), s1_len, new_child);
2014-05-16 08:38:14 -04:00
// 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]);
2014-05-16 08:38:14 -04:00
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
2014-05-20 13:15:54 -04:00
new_child->endpoint = e->child->endpoint;
e->child->endpoint = 0; // reset endpoint
2014-05-16 08:38:14 -04:00
// Migrate the data
2014-05-18 07:09:47 -04:00
new_child->data = e->child->data; // copy data pointer
2014-05-18 03:00:11 -04:00
e->child->data = NULL;
r3_node_append_edge(e->child, e1);
// truncate the original edge pattern
2014-05-22 23:14:26 -04:00
char *oldpattern = e->pattern;
2014-05-21 04:18:12 -04:00
e->pattern = zstrndup(e->pattern, dl);
e->pattern_len = dl;
2014-05-22 23:14:26 -04:00
zfree(oldpattern);
2014-05-18 08:16:53 -04:00
return new_child;
2014-05-16 08:38:14 -04:00
}
void r3_edge_free(edge * e) {
zfree(e->pattern);
2014-05-16 08:38:14 -04:00
if ( e->child ) {
r3_tree_free(e->child);
}
2014-05-21 06:12:14 -04:00
// free itself
zfree(e);
2014-05-16 08:38:14 -04:00
}