Compare commits

...

14 commits
2.0 ... mempool

Author SHA1 Message Date
c9s 7251740668 Add mempool to Makefile.am 2015-11-12 22:15:40 +08:00
c9s e09667818e Add mempool 2015-11-12 22:15:35 +08:00
c9s 576d568c16 use __attribute aligned to align struct 2015-11-12 22:01:55 +08:00
c9s 2dc8cc1533 Adjust window size 2015-11-11 11:17:43 +08:00
c9s ae191a1d75 Add padding to node struct 2015-11-11 11:16:19 +08:00
c9s 60376804b0 Add 2.0 to changelog 2015-11-11 11:08:35 +08:00
c9s 257ced4717 Add padding to edge structure 2015-11-11 11:08:09 +08:00
c9s 985c8593dd Remove unneccessary comments from struct 2015-11-10 21:02:47 +08:00
c9s 7e08440d0c Merge branch 'gnu-likely' into 2.0 2015-11-10 20:43:16 +08:00
c9s 3041469007 Move variable positions 2015-11-10 20:42:41 +08:00
c9s 7e545159a0 Add GNU likely/unlikely support 2015-11-10 20:41:52 +08:00
c9s e401364869 Cache pointer of edge 2015-11-10 20:31:36 +08:00
c9s 03448d72cf Merge branch 'edge-array' into 2.0 2015-11-10 20:30:07 +08:00
c9s fd9388437e Make edges as an array
Fixes: #89
2015-11-10 20:29:07 +08:00
11 changed files with 175 additions and 74 deletions

View file

@ -3,6 +3,11 @@
by Yo-An Lin <yoanlin93@gmail.com>
### 2.0 - Wed Nov 11 11:08:22 2015
### 1.3.3 - Sat Jun 28 00:53:48 2014
- Fix graphviz generator.

View file

@ -150,12 +150,17 @@
var lines = data.split(/\n/);
// keep window size to 30 records
lines.splice(-30);
lines = lines.splice(lines.length - 30);
// keep window size to 60 records
lines = lines.splice(-60);
$(lines).each(function(i,line) {
if (line == "") {
return;
}
var columns = line.split(/,/);
if (columns.length == 0) {
return;
}
var a;
a = parseInt(columns[1]);
options.series[0].data.push(a || 0);

View file

@ -626,3 +626,19 @@
1447156411,13229275.90,5858750.37,66576.25,2523350.73
1447156432,13556025.90,5873947.56,62601.55,2487130.01
1447156745,13744909.39,5913103.69,66576.25,2551782.92
1447158285,11638128.71,5241775.30,71089.90,2321077.83
1447158396,13539837.29,5874704.47,47662.55,2533571.93
1447158415,14054879.53,5952300.47,41527.76,2571669.83
1447210457,13616841.50,5604087.24,83886.08,2458628.97
1447210807,14529897.99,5833087.33,77672.30,1845729.06
1447210834,14016924.69,5806227.80,66576.25,1715107.19
1447211104,14738120.40,5873312.56,58254.22,2092537.05
1447211128,14875503.82,5649431.95,27776.85,2033045.40
1447211244,15335902.86,6019829.26,77672.30,1842297.15
1447211259,14365504.46,5812325.12,91180.52,1965977.09
1447211278,15175749.51,5931324.37,99864.38,1905029.23
1447211529,15442994.79,5909448.56,91180.52,1953744.42
1447211564,15175229.72,6100062.87,58254.22,1918667.68
1447211712,15957717.02,6145969.23,77672.30,1960098.15
1447211732,15692151.82,5725138.47,62601.55,1711560.29
1447211755,15758474.73,6033801.22,82241.25,1995758.04

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

View file

@ -27,40 +27,28 @@ typedef struct _edge edge;
typedef struct _node node;
typedef struct _route route;
struct _node {
edge ** edges;
// edge ** edge_table;
struct _node {
edge * edges;
char * combined_pattern;
pcre * pcre_pattern;
// #ifdef PCRE_STUDY_JIT_COMPILE
pcre_extra * pcre_extra;
// #endif
// edges are mostly less than 255
unsigned int edge_len;
unsigned int compare_type; // compare_type: pcre, opcode, string
unsigned char endpoint; // endpoint, should be zero for non-endpoint nodes
unsigned char ov_cnt; // capture vector array size for pcre
unsigned int edge_len;
unsigned int endpoint; // endpoint, should be zero for non-endpoint nodes
unsigned int ov_cnt; // capture vector array size for pcre
route ** routes;
// the pointer of route data
void * data;
// almost less than 255
unsigned char edge_cap;
unsigned char route_len;
unsigned char route_cap;
// <-- here comes a char[1] struct padding for alignment since we have 4 char above.
/** compile-time variables here.... **/
/* the combined regexp pattern string from pattern_tokens */
route ** routes;
/**
* the pointer of route data
*/
void * data;
};
} __attribute((aligned(64)));
#define r3_node_edge_pattern(node,i) node->edges[i]->pattern
#define r3_node_edge_pattern_len(node,i) node->edges[i]->pattern_len
@ -68,11 +56,10 @@ struct _node {
struct _edge {
char * pattern; // 8 bytes
node * child; // 8 bytes
unsigned int pattern_len; // 1 byte
unsigned int opcode;
// unsigned char opcode:4; // 4 bit
unsigned char has_slug:1; // 1 bit
};
unsigned int pattern_len; // 4byte
unsigned int opcode; // 4byte
unsigned int has_slug; // 4byte
} __attribute((aligned(64)));
struct _route {
char * path;
@ -87,7 +74,7 @@ struct _route {
char * remote_addr_pattern;
int remote_addr_pattern_len;
};
} __attribute((aligned(64)));
typedef struct {
str_array * vars;
@ -123,7 +110,7 @@ edge * r3_node_connectl(node * n, const char * pat, int len, int strdup, node *c
edge * r3_node_find_edge(const node * n, const char * pat, int pat_len);
void r3_node_append_edge(node *n, edge *child);
edge * r3_node_append_edge(node *n, edge *child);
edge * r3_node_find_common_prefix(node *n, const char *path, int path_len, int *prefix_len, char **errstr);
@ -171,6 +158,8 @@ bool r3_node_has_slug_edges(const node *n);
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child);
void r3_edge_initl(edge *e, const char * pattern, int pattern_len, node * child);
node * r3_edge_branch(edge *e, int dl);
void r3_edge_free(edge * edge);

View file

@ -4,7 +4,7 @@ MAYBE_COVERAGE=--coverage
noinst_LTLIBRARIES = libr3core.la
# lib_LIBRARIES = libr3.a
libr3core_la_SOURCES = node.c edge.c str.c token.c match_entry.c slug.c
libr3core_la_SOURCES = node.c edge.c str.c token.c match_entry.c slug.c mempool.c
if ENABLE_JSON
libr3core_la_SOURCES += json.c

View file

@ -24,11 +24,20 @@
#define CHECK_PTR(ptr) if (ptr == NULL) return NULL;
edge * r3_edge_createl(const char * pattern, int pattern_len, node * child) {
void r3_edge_initl(edge *e, const char * pattern, int pattern_len, node * child)
{
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);
}
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;
@ -60,9 +69,9 @@ node * r3_edge_branch(edge *e, int 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;
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;

43
src/mempool.c Normal file
View file

@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include "mempool.h"
void ex_mpool_init(ex_mpool *pmp, char *begin, size_t len)
{
pmp->begin = begin;
pmp->len = len;
pmp->index = 0;
pmp->cflag = 0;
}
void *ex_mpool_malloc(ex_mpool *pmp, size_t mlen)
{
void *ret = NULL;
size_t rIndex = pmp->index + mlen;
if (rIndex > pmp->len) {
ret = malloc(mlen);
pmp->cflag = 1;
}
else {
ret = pmp->begin + pmp->index;
pmp->index = rIndex;
}
return ret;
}
void ex_mpool_free(ex_mpool *pmp, void *p)
{
/* only perform free when allocated in heap */
if (p < (void *) pmp->begin ||
p >= (void *) (pmp->begin + pmp->len)) {
free(p);
}
}
void ex_mpool_clear(ex_mpool *pmp)
{
pmp->index = 0;
pmp->cflag = 0;
}

24
src/mempool.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef __ESERV_MPOOL_H__
#define __ESERV_MPOOL_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
char *begin; /* start pos */
size_t len; /* capacity */
int index; /* curIndex */
int cflag; /* clear flag */
} ex_mpool;
void ex_mpool_init(ex_mpool *pmp, char *begin, size_t len);
void *ex_mpool_malloc(ex_mpool *pmp, size_t mlen);
void ex_mpool_free(ex_mpool *pmp, void *p);
void ex_mpool_clear(ex_mpool *pmp);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -13,6 +13,13 @@
#include "slug.h"
#include "zmalloc.h"
#ifdef __GNUC__
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
#else
# define likely(x) !!(x)
# define unlikely(x) !!(x)
#endif
#define CHECK_PTR(ptr) if (ptr == NULL) return NULL;
@ -47,7 +54,7 @@ node * r3_tree_create(int cap) {
node * n = (node*) zmalloc( sizeof(node) );
CHECK_PTR(n);
n->edges = (edge**) zmalloc( sizeof(edge*) * cap );
n->edges = (edge*) zmalloc(sizeof(edge) * cap);
CHECK_PTR(n->edges);
n->edge_len = 0;
n->edge_cap = cap;
@ -65,12 +72,9 @@ node * r3_tree_create(int cap) {
}
void r3_tree_free(node * tree) {
for (int i = 0 ; i < tree->edge_len ; i++ ) {
if (tree->edges[i]) {
r3_edge_free(tree->edges[ i ]);
}
if (tree->edges) {
zfree(tree->edges);
}
zfree(tree->edges);
zfree(tree->routes);
if (tree->pcre_pattern) {
pcre_free(tree->pcre_pattern);
@ -104,23 +108,29 @@ edge * r3_node_connectl(node * n, const char * pat, int len, int dupl, node *chi
}
e = r3_edge_createl(pat, len, child);
CHECK_PTR(e);
r3_node_append_edge(n, e);
return e;
edge *e2 = r3_node_append_edge(n, e);
zfree(e);
return e2;
}
void r3_node_append_edge(node *n, edge *e) {
edge * r3_node_append_edge(node *n, edge *e)
{
if (n->edges == NULL) {
n->edge_cap = 3;
n->edges = zmalloc(sizeof(edge) * n->edge_cap);
}
if (n->edge_len >= n->edge_cap) {
n->edge_cap *= 2;
edge ** p = zrealloc(n->edges, sizeof(edge) * n->edge_cap);
edge * p = zrealloc(n->edges, sizeof(edge) * n->edge_cap);
if(p) {
n->edges = p;
}
}
n->edges[ n->edge_len++ ] = e;
// r3_edge_initl(
// copy 'edge' into the edge array
n->edges[n->edge_len] = *e;
return &n->edges[n->edge_len++];
}
@ -133,11 +143,10 @@ edge * r3_node_find_edge(const node * n, const char * pat, int pat_len) {
edge * e;
int i;
for (i = 0 ; i < n->edge_len ; i++ ) {
e = n->edges[i];
e = &n->edges[i];
// there is a case: "{foo}" vs "{foo:xxx}",
// we should return the match result: full-match or partial-match
if ( strcmp(e->pattern, pat) == 0 ) {
if (strcmp(e->pattern, pat) == 0) {
return e;
}
}
@ -146,6 +155,7 @@ edge * r3_node_find_edge(const node * n, const char * pat, int pat_len) {
int r3_tree_compile(node *n, char **errstr)
{
int i;
int ret = 0;
bool use_slug = r3_node_has_slug_edges(n);
if ( use_slug ) {
@ -157,8 +167,8 @@ int r3_tree_compile(node *n, char **errstr)
n->combined_pattern = NULL;
}
for (int i = 0 ; i < n->edge_len ; i++ ) {
if ( (ret = r3_tree_compile(n->edges[i]->child, errstr)) ) {
for (i = 0 ; i < n->edge_len ; i++ ) {
if ((ret = r3_tree_compile(n->edges[i].child, errstr))) {
return ret; // stop here if error occurs
}
}
@ -173,7 +183,7 @@ int r3_tree_compile(node *n, char **errstr)
* Return 0 if success
*/
int r3_tree_compile_patterns(node * n, char **errstr) {
edge * e = NULL;
edge *e = NULL;
char * p;
char * cpat = zcalloc(sizeof(char) * 64 * 3); // XXX
if (!cpat) {
@ -185,7 +195,7 @@ int r3_tree_compile_patterns(node * n, char **errstr) {
int opcode_cnt = 0;
int i = 0;
for (; i < n->edge_len ; i++) {
e = n->edges[i];
e = &n->edges[i];
if (e->opcode) {
opcode_cnt++;
}
@ -286,7 +296,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
for (i = n->edge_len; i--; ) {
pp = path;
e = n->edges[i];
e = &n->edges[i];
switch(e->opcode) {
case OP_EXPECT_NOSLASH:
while (*pp != '/' && pp < pp_end) pp++;
@ -305,7 +315,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
break;
}
// check match
if ( (pp - path) > 0) {
if ((pp - path) > 0) {
if (entry) {
str_array_append(entry->vars , zstrndup(path, pp - path));
}
@ -372,7 +382,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
continue;
substring_start = path + ov[2*i];
e = n->edges[i - 1];
e = &n->edges[i - 1];
if (entry && e->has_slug) {
// append captured token to entry
@ -396,7 +406,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
}
substring_start = path + ov[2*i];
e = n->edges[i - 1];
e = &n->edges[i - 1];
if (entry && e->has_slug) {
// append captured token to entry
@ -410,7 +420,7 @@ node * r3_tree_matchl(const node * n, const char * path, int path_len, match_ent
return NULL;
}
if ( (e = r3_node_find_edge_str(n, path, path_len)) != NULL ) {
if ((e = r3_node_find_edge_str(n, path, path_len)) != NULL) {
restlen = path_len - e->pattern_len;
if (restlen == 0) {
return e->child && e->child->endpoint > 0 ? e->child : NULL;
@ -437,13 +447,14 @@ route * r3_tree_match_route(const node *tree, match_entry * entry) {
}
inline edge * r3_node_find_edge_str(const node * n, const char * str, int str_len) {
char firstbyte = *str;
edge * e;
unsigned int i;
char firstbyte = *str;
for (i = n->edge_len; i--; ) {
edge *e = n->edges[i];
e = &n->edges[i];
if (firstbyte == e->pattern[0]) {
if (strncmp(e->pattern, str, e->pattern_len) == 0 ) {
return n->edges[i];
if (strncmp(e->pattern, str, e->pattern_len) == 0) {
return &n->edges[i];
}
return NULL;
}
@ -531,11 +542,11 @@ edge * r3_node_find_common_prefix(node *n, const char *path, int path_len, int *
edge *e = NULL;
for(i = 0 ; i < n->edge_len ; i++ ) {
// ignore all edges with slug
prefix = strndiff( (char*) path, n->edges[i]->pattern, n->edges[i]->pattern_len);
prefix = strndiff( (char*) path, n->edges[i].pattern, n->edges[i].pattern_len);
// no common, consider insert a new edge
if ( prefix > 0 ) {
e = n->edges[i];
e = &n->edges[i];
break;
}
}
@ -753,7 +764,7 @@ bool r3_node_has_slug_edges(const node *n) {
bool found = FALSE;
edge *e;
for ( int i = 0 ; i < n->edge_len ; i++ ) {
e = n->edges[i];
e = &n->edges[i];
e->has_slug = r3_path_contains_slug_char(e->pattern);
if (e->has_slug)
found = TRUE;
@ -780,7 +791,7 @@ void r3_tree_dump(const node * n, int level) {
printf("\n");
for ( int i = 0 ; i < n->edge_len ; i++ ) {
edge * e = n->edges[i];
edge * e = &n->edges[i];
print_indent(level + 1);
printf("|-\"%s\"", e->pattern);

View file

@ -1,5 +1,4 @@
# set(TEST_LIBS ${TEST_LIBS} ${CHECK_LIBRARIES} judy libr3)
# set(TEST_LIBS ${TEST_LIBS} ${CHECK_LIBRARIES} judy libr3)
include_directories("${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}")
find_package(Check REQUIRED)
find_package(PCRE REQUIRED)

View file

@ -20,7 +20,7 @@
unsigned long unixtime() {
struct timeval tp;
if (gettimeofday((struct timeval *) &tp, (NUL)) == 0) {
if (gettimeofday((struct timeval *) &tp, (NULL)) == 0) {
return tp.tv_sec;
}
return 0;
@ -30,7 +30,7 @@ double microtime() {
struct timeval tp;
long sec = 0L;
double msec = 0.0;
if (gettimeofday((struct timeval *) &tp, (NUL)) == 0) {
if (gettimeofday((struct timeval *) &tp, (NULL)) == 0) {
msec = (double) (tp.tv_usec / MICRO_IN_SEC);
sec = tp.tv_sec;
if (msec >= 1.0)