Compare commits
24 commits
2.0
...
feature/st
Author | SHA1 | Date | |
---|---|---|---|
|
0f5ebed73c | ||
|
0b499c9158 | ||
|
76e4b15787 | ||
|
546fcb14af | ||
|
faaaeb5f90 | ||
|
8471f42579 | ||
|
3cbffb645c | ||
|
1563bd5a78 | ||
|
adbe71d336 | ||
|
d73a3aa89a | ||
|
a4378fdaf2 | ||
|
3121937da5 | ||
|
c421bea11f | ||
|
5ada611182 | ||
|
ba270b5948 | ||
|
24aaa881b1 | ||
|
595dadba15 | ||
|
d6b2e52567 | ||
|
2b331ecc8f | ||
|
21a8c0c891 | ||
|
a5035ad962 | ||
|
3500e19316 | ||
|
58b74b9126 | ||
|
f8154b23e9 |
8 changed files with 315 additions and 45 deletions
61
bench.html
61
bench.html
|
@ -70,10 +70,43 @@
|
|||
},
|
||||
|
||||
tooltip: {
|
||||
// headerFormat: '<span style="font-size: 10px">{point.key}: </span><br/>',
|
||||
formatter: function() {
|
||||
var s = '';
|
||||
|
||||
var comment = this.points[1].point.comment;
|
||||
// new Date(this.x) + ':';
|
||||
if (comment) {
|
||||
s += '<span style="font-size: 10px;">';
|
||||
s += comment;
|
||||
s += '</span><br/>';
|
||||
}
|
||||
|
||||
$.each(this.points, function(i, point) {
|
||||
s += '<span style="color:' + point.series.color + '">\u25CF</span> ' + point.series.name + ': <b>' + point.y + '</b><br/>';
|
||||
});
|
||||
return s;
|
||||
},
|
||||
shared: true,
|
||||
crosshairs: true
|
||||
},
|
||||
|
||||
/*
|
||||
tooltip: {
|
||||
formatter: function() {
|
||||
var s = '';
|
||||
$.each(this.points, function(i, point) {
|
||||
s += point.series.name +': '+ point.y + '<br/>';
|
||||
});
|
||||
if (this.points[1] && this.points[1].comment) {
|
||||
s += '<b>'+ this.points[1].comment +'</b>';
|
||||
}
|
||||
return s;
|
||||
},
|
||||
shared: true
|
||||
},
|
||||
*/
|
||||
|
||||
plotOptions: {
|
||||
/*
|
||||
area: {
|
||||
|
@ -148,19 +181,23 @@
|
|||
|
||||
var lines = data.split(/\n/);
|
||||
$(lines).each(function(i,line) {
|
||||
|
||||
/*
|
||||
{ marker: {
|
||||
fillColor: '#FF0000',
|
||||
lineWidth: 3,
|
||||
lineColor: "#FF0000" // inherit from series
|
||||
}
|
||||
*/
|
||||
var columns = line.split(/,/);
|
||||
var a;
|
||||
a = parseInt(columns[1]);
|
||||
options.series[0].data.push(a || 0);
|
||||
|
||||
a = parseInt(columns[2]);
|
||||
options.series[1].data.push(a || 0);
|
||||
|
||||
a = parseInt(columns[3]);
|
||||
options.series[2].data.push(a || 0);
|
||||
|
||||
a = parseInt(columns[4]);
|
||||
options.series[3].data.push(a || 0);
|
||||
var commentText = columns[5];
|
||||
for (var i = 1; i < 5; i++ ) {
|
||||
var a = parseInt(columns[i]);
|
||||
var args = a ?
|
||||
(commentText ? { y: a, comment: commentText } : a)
|
||||
: 0;
|
||||
options.series[i-1].data.push(args);
|
||||
}
|
||||
});
|
||||
|
||||
$('#chart').highcharts(options);
|
||||
|
|
|
@ -443,6 +443,23 @@
|
|||
1400668574,13632260.72
|
||||
1400681414,10832905.89
|
||||
1400685490,13185955.87
|
||||
1400748100,12609470.07
|
||||
1400748288,13317009.48
|
||||
1400748727,12973679.22
|
||||
1400748826,12902583.84
|
||||
1400748965,13584323.91
|
||||
1400749175,13518288.33
|
||||
1400749320,13445606.30
|
||||
1400749326,13242705.99
|
||||
1400749599,13245418.70
|
||||
1400749614,12494314.81
|
||||
1400749643,12690632.63
|
||||
1400750350,10391028.46
|
||||
1400750424,9445761.22
|
||||
1400750472,9248611.74
|
||||
1400750479,10757562.36
|
||||
1400750512,10126746.58
|
||||
1400750536,10568568.26
|
||||
1400762875,10472029.42
|
||||
1400764426,10066458.45,1590373.41
|
||||
1400765068,10657617.64,2131810.12
|
||||
|
@ -511,3 +528,11 @@
|
|||
1400837774,11190990.08,4331119.44,45590.26,2587281.10
|
||||
1400837785,10306507.50,3909290.89,47662.55,2827471.10
|
||||
1400837797,10323334.38,4221122.48,55924.05,2294463.55
|
||||
1400858847,10663450.41,4674634.54,66576.25,2653715.59
|
||||
1400858857,10336003.37,4496145.54,59074.70,2607583.19
|
||||
1400858869,9640828.18,4607189.58,66576.25,2268341.79
|
||||
1400858880,10959344.32,4114165.27,41943.04,2405089.57
|
||||
1400858891,9456420.72,4254882.18,33554.43,2770969.36
|
||||
1400858902,10904696.64,3989404.21,72315.59,2410755.81
|
||||
1400858913,9379941.50,4385508.67,49932.19,2595906.55
|
||||
1400858923,10653302.72,4655704.49,55188.21,2677379.49
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 464.
|
118
config.h.in
Normal file
118
config.h.in
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* "whether graphviz is enable" */
|
||||
#undef ENABLE_GRAPHVIZ
|
||||
|
||||
/* "whether statistics is enable" */
|
||||
#undef ENABLE_STATS
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <jemalloc/jemalloc.h> header file. */
|
||||
#undef HAVE_JEMALLOC_JEMALLOC_H
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#undef HAVE_MALLOC
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#undef HAVE_MEMSET
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#undef HAVE_REALLOC
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strndup' function. */
|
||||
#undef HAVE_STRNDUP
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#undef HAVE_STRSTR
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you have the PATH_MAX macro. */
|
||||
#undef USE_JEMALLOC
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
#undef malloc
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
#undef realloc
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
46
configure.ac
46
configure.ac
|
@ -7,7 +7,8 @@ LT_INIT
|
|||
AC_PROG_CC
|
||||
AC_PROG_CC_STDC
|
||||
|
||||
# AM_PATH_CHECK()
|
||||
AC_CHECK_HEADERS([stdlib.h string.h sys/time.h stdint.h])
|
||||
|
||||
PKG_CHECK_MODULES(CHECK,[check >= 0.9.4],:,[
|
||||
ifdef([AM_PATH_CHECK],
|
||||
[AM_PATH_CHECK(,[have_check="yes"])],
|
||||
|
@ -16,8 +17,6 @@ PKG_CHECK_MODULES(CHECK,[check >= 0.9.4],:,[
|
|||
])
|
||||
AM_CONDITIONAL(HAVE_CHECK, test x"$have_check" = "xyes")
|
||||
|
||||
AC_CHECK_HEADERS([stdlib.h string.h sys/time.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
|
@ -31,23 +30,10 @@ AC_CHECK_FUNCS([gettimeofday memset strchr strdup strndup strstr])
|
|||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_ARG_ENABLE(graphviz,
|
||||
AS_HELP_STRING([--enable-graphviz],
|
||||
[enable graphviz support]),
|
||||
, enable_graphviz=unset)
|
||||
if test "x$enable_graphviz" != "xunset" ; then
|
||||
PKG_CHECK_MODULES(GVC_DEPS, [libgvc])
|
||||
AC_SUBST(GVC_DEPS_CFLAGS)
|
||||
AC_SUBST(GVC_DEPS_LIBS)
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
AS_HELP_STRING([--enable-debug],
|
||||
[enable debug]),
|
||||
, enable_debug=unset)
|
||||
|
||||
AC_ARG_WITH([malloc],
|
||||
AS_HELP_STRING([--without-malloc], [Use the default malloc]))
|
||||
|
||||
AC_ARG_WITH([malloc], AS_HELP_STRING([--without-malloc], [Use the default malloc]))
|
||||
|
||||
AS_IF([test "x$with_malloc" == "xjemalloc"],
|
||||
[AC_CHECK_HEADERS([jemalloc/jemalloc.h], [
|
||||
|
@ -77,16 +63,32 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <jemalloc/jemalloc.h>]],
|
|||
)
|
||||
fi
|
||||
AM_CONDITIONAL(USE_JEMALLOC, test "x$have_jemalloc" = "xyes")
|
||||
AM_CONDITIONAL(ENABLE_GRAPHVIZ, test "x$enable_graphviz" = "xyes")
|
||||
|
||||
# AM_CONDITIONAL(USE_JEMALLOC, test "x$found_jemalloc" = "xyes")
|
||||
# AC_DEFINE(USE_JEMALLOC, test "x$found_jemalloc" = "xyes" , "use jemalloc")
|
||||
|
||||
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [enable debug]), [],[enable_debug=unset])
|
||||
AM_CONDITIONAL(ENABLE_DEBUG, test "x$enable_debug" = "xyes")
|
||||
|
||||
|
||||
AC_ARG_ENABLE(graphviz,
|
||||
AS_HELP_STRING([--enable-graphviz],
|
||||
[enable graphviz support]),
|
||||
, enable_graphviz=unset)
|
||||
if test "x$enable_graphviz" != "xunset" ; then
|
||||
PKG_CHECK_MODULES(GVC_DEPS, [libgvc])
|
||||
AC_SUBST(GVC_DEPS_CFLAGS)
|
||||
AC_SUBST(GVC_DEPS_LIBS)
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_GRAPHVIZ, test "x$enable_graphviz" = "xyes")
|
||||
AC_DEFINE(ENABLE_GRAPHVIZ, test "x$enable_graphviz" = "xyes", "whether graphviz is enable")
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(DEPS, [libpcre check])
|
||||
AC_ARG_ENABLE(stats, AS_HELP_STRING([--enable-stats], [enable statistics]), [] ,[enable_stats=unset])
|
||||
AC_DEFINE(ENABLE_STATS, test "x$enable_stats" = "xyes", "whether statistics is enable")
|
||||
|
||||
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(DEPS, [libpcre])
|
||||
AC_SUBST(DEPS_CFLAGS)
|
||||
AC_SUBST(DEPS_LIBS)
|
||||
AC_CONFIG_FILES([
|
||||
|
|
35
include/r3.h
35
include/r3.h
|
@ -15,27 +15,40 @@
|
|||
|
||||
#include "r3_define.h"
|
||||
#include "str_array.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
|
||||
#define node_edge_pattern(node,i) node->edges[i]->pattern
|
||||
#define node_edge_pattern_len(node,i) node->edges[i]->pattern_len
|
||||
|
||||
|
||||
struct _root;
|
||||
struct _edge;
|
||||
struct _node;
|
||||
struct _route;
|
||||
typedef struct _edge edge;
|
||||
typedef struct _node node;
|
||||
typedef struct _route route;
|
||||
typedef struct _root root;
|
||||
|
||||
struct _root {
|
||||
|
||||
};
|
||||
|
||||
struct _node {
|
||||
edge ** edges;
|
||||
route ** routes;
|
||||
int edge_len;
|
||||
int edge_cap;
|
||||
int route_len;
|
||||
int route_cap;
|
||||
int endpoint;
|
||||
edge * parent_edge;
|
||||
uint32_t edge_len;
|
||||
uint32_t edge_cap;
|
||||
uint32_t route_len;
|
||||
uint32_t route_cap;
|
||||
|
||||
/** compile-time variables here.... **/
|
||||
|
||||
|
@ -50,14 +63,20 @@ struct _node {
|
|||
*/
|
||||
void * data;
|
||||
|
||||
uint8_t endpoint;
|
||||
};
|
||||
|
||||
struct _edge {
|
||||
/* the child node */
|
||||
node * child;
|
||||
/* the parent node */
|
||||
node * parent;
|
||||
|
||||
char * pattern;
|
||||
int pattern_len;
|
||||
int opcode;
|
||||
bool has_slug;
|
||||
node * child;
|
||||
float score;
|
||||
bool has_slug:1;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -167,6 +186,8 @@ void r3_route_free(route * route);
|
|||
|
||||
route * r3_tree_match_route(const node *n, match_entry * entry);
|
||||
|
||||
void r3_tree_feedback(node *tree, node *end);
|
||||
|
||||
#define METHOD_GET 2
|
||||
#define METHOD_POST 2<<1
|
||||
#define METHOD_PUT 2<<2
|
||||
|
|
10
src/edge.c
10
src/edge.c
|
@ -30,6 +30,14 @@ edge * r3_edge_create(char * pattern, int pattern_len, node * child) {
|
|||
e->pattern_len = pattern_len;
|
||||
e->opcode = 0;
|
||||
e->child = child;
|
||||
e->parent = NULL;
|
||||
|
||||
// update childs parent edge
|
||||
child->parent_edge = e;
|
||||
|
||||
// default stats
|
||||
// e->hits = 0;
|
||||
e->score = 0;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -56,6 +64,8 @@ node * r3_edge_branch(edge *e, int dl) {
|
|||
// the suffix edge of the leaf
|
||||
new_child = r3_tree_create(3);
|
||||
s1_len = e->pattern_len - dl;
|
||||
|
||||
/* create the parent edge of new child */
|
||||
e1 = r3_edge_create(zstrndup(s1, s1_len), s1_len, new_child);
|
||||
|
||||
// Migrate the child edges to the new edge we just created.
|
||||
|
|
28
src/node.c
28
src/node.c
|
@ -45,6 +45,8 @@ node * r3_tree_create(int cap) {
|
|||
n->edge_len = 0;
|
||||
n->edge_cap = cap;
|
||||
|
||||
n->parent_edge = NULL;
|
||||
|
||||
n->routes = NULL;
|
||||
n->route_len = 0;
|
||||
n->route_cap = 0;
|
||||
|
@ -95,6 +97,26 @@ edge * r3_node_connectl(node * n, char * pat, int len, int dupl, node *child) {
|
|||
return e;
|
||||
}
|
||||
|
||||
void r3_tree_feedback(node *tree, node *end) {
|
||||
edge * e = end->parent_edge;
|
||||
node * p = e->parent;
|
||||
while( p && e ) {
|
||||
e->score += 0.1;
|
||||
|
||||
|
||||
if (e->score > 100) {
|
||||
for (int i = 0 ; i < p->edge_len ; i++ ) {
|
||||
if ( p->edges[i]->score > 0 ) {
|
||||
p->edges[i]->score /= 100.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e = p->parent_edge;
|
||||
p = e ? e->parent : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void r3_node_append_edge(node *n, edge *e) {
|
||||
if (n->edges == NULL) {
|
||||
n->edge_cap = 3;
|
||||
|
@ -107,6 +129,8 @@ void r3_node_append_edge(node *n, edge *e) {
|
|||
n->edges = p;
|
||||
}
|
||||
}
|
||||
// when append new edge, we update the parent node of the edge.
|
||||
e->parent = n;
|
||||
n->edges[ n->edge_len++ ] = e;
|
||||
}
|
||||
|
||||
|
@ -408,6 +432,8 @@ node * r3_node_create() {
|
|||
n->edge_len = 0;
|
||||
n->edge_cap = 0;
|
||||
|
||||
n->parent_edge = NULL;
|
||||
|
||||
n->routes = NULL;
|
||||
n->route_len = 0;
|
||||
n->route_cap = 0;
|
||||
|
@ -636,6 +662,8 @@ void r3_tree_dump(node * n, int level) {
|
|||
print_indent(level + 1);
|
||||
printf("|-\"%s\"", e->pattern);
|
||||
|
||||
// printf(" hits:%lld score:%.1f ", e->hits, e->score);
|
||||
printf(" score:%.1f ", e->score);
|
||||
if (e->opcode ) {
|
||||
printf(" opcode:%d", e->opcode);
|
||||
}
|
||||
|
|
|
@ -361,6 +361,34 @@ START_TEST(test_insert_route)
|
|||
END_TEST
|
||||
|
||||
|
||||
START_TEST(test_feedback)
|
||||
{
|
||||
node * t = r3_tree_create(1);
|
||||
r3_tree_insert_path(t, "/foo/bar/baz", NULL);
|
||||
r3_tree_insert_path(t, "/foo/grault/bar", NULL);
|
||||
r3_tree_insert_path(t, "/garply/corge/grault", NULL);
|
||||
r3_tree_compile(t);
|
||||
|
||||
node * m1 = r3_tree_match(t, "/foo/grault/bar", NULL);
|
||||
node * m2 = r3_tree_match(t, "/garply/corge/grault", NULL);
|
||||
ck_assert(m1 != NULL);
|
||||
ck_assert(m2 != NULL);
|
||||
|
||||
for ( int i = 0 ; i < 120 ; i++ ) {
|
||||
r3_tree_feedback(t, m1);
|
||||
}
|
||||
|
||||
for ( int i = 0 ; i < 200 ; i++ ) {
|
||||
r3_tree_feedback(t, m2);
|
||||
}
|
||||
|
||||
r3_tree_dump(t, 0);
|
||||
|
||||
r3_tree_free(t);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
Suite* r3_suite (void) {
|
||||
Suite *suite = suite_create("blah");
|
||||
|
||||
|
@ -379,6 +407,7 @@ Suite* r3_suite (void) {
|
|||
tcase_add_test(tcase, test_pcre_patterns_insert);
|
||||
tcase_add_test(tcase, test_pcre_patterns_insert_2);
|
||||
tcase_add_test(tcase, test_pcre_patterns_insert_3);
|
||||
tcase_add_test(tcase, test_feedback);
|
||||
tcase_set_timeout(tcase, 30);
|
||||
|
||||
suite_add_tcase(suite, tcase);
|
||||
|
|
Loading…
Reference in a new issue