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: {
|
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,
|
shared: true,
|
||||||
crosshairs: 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: {
|
plotOptions: {
|
||||||
/*
|
/*
|
||||||
area: {
|
area: {
|
||||||
|
@ -148,19 +181,23 @@
|
||||||
|
|
||||||
var lines = data.split(/\n/);
|
var lines = data.split(/\n/);
|
||||||
$(lines).each(function(i,line) {
|
$(lines).each(function(i,line) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
{ marker: {
|
||||||
|
fillColor: '#FF0000',
|
||||||
|
lineWidth: 3,
|
||||||
|
lineColor: "#FF0000" // inherit from series
|
||||||
|
}
|
||||||
|
*/
|
||||||
var columns = line.split(/,/);
|
var columns = line.split(/,/);
|
||||||
var a;
|
var commentText = columns[5];
|
||||||
a = parseInt(columns[1]);
|
for (var i = 1; i < 5; i++ ) {
|
||||||
options.series[0].data.push(a || 0);
|
var a = parseInt(columns[i]);
|
||||||
|
var args = a ?
|
||||||
a = parseInt(columns[2]);
|
(commentText ? { y: a, comment: commentText } : a)
|
||||||
options.series[1].data.push(a || 0);
|
: 0;
|
||||||
|
options.series[i-1].data.push(args);
|
||||||
a = parseInt(columns[3]);
|
}
|
||||||
options.series[2].data.push(a || 0);
|
|
||||||
|
|
||||||
a = parseInt(columns[4]);
|
|
||||||
options.series[3].data.push(a || 0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#chart').highcharts(options);
|
$('#chart').highcharts(options);
|
||||||
|
|
|
@ -443,6 +443,23 @@
|
||||||
1400668574,13632260.72
|
1400668574,13632260.72
|
||||||
1400681414,10832905.89
|
1400681414,10832905.89
|
||||||
1400685490,13185955.87
|
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
|
1400762875,10472029.42
|
||||||
1400764426,10066458.45,1590373.41
|
1400764426,10066458.45,1590373.41
|
||||||
1400765068,10657617.64,2131810.12
|
1400765068,10657617.64,2131810.12
|
||||||
|
@ -511,3 +528,11 @@
|
||||||
1400837774,11190990.08,4331119.44,45590.26,2587281.10
|
1400837774,11190990.08,4331119.44,45590.26,2587281.10
|
||||||
1400837785,10306507.50,3909290.89,47662.55,2827471.10
|
1400837785,10306507.50,3909290.89,47662.55,2827471.10
|
||||||
1400837797,10323334.38,4221122.48,55924.05,2294463.55
|
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
|
||||||
AC_PROG_CC_STDC
|
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],:,[
|
PKG_CHECK_MODULES(CHECK,[check >= 0.9.4],:,[
|
||||||
ifdef([AM_PATH_CHECK],
|
ifdef([AM_PATH_CHECK],
|
||||||
[AM_PATH_CHECK(,[have_check="yes"])],
|
[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")
|
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.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
|
@ -31,23 +30,10 @@ AC_CHECK_FUNCS([gettimeofday memset strchr strdup strndup strstr])
|
||||||
|
|
||||||
PKG_PROG_PKG_CONFIG
|
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"],
|
AS_IF([test "x$with_malloc" == "xjemalloc"],
|
||||||
[AC_CHECK_HEADERS([jemalloc/jemalloc.h], [
|
[AC_CHECK_HEADERS([jemalloc/jemalloc.h], [
|
||||||
|
@ -77,16 +63,32 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <jemalloc/jemalloc.h>]],
|
||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(USE_JEMALLOC, test "x$have_jemalloc" = "xyes")
|
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_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [enable debug]), [],[enable_debug=unset])
|
||||||
# AC_DEFINE(USE_JEMALLOC, test "x$found_jemalloc" = "xyes" , "use jemalloc")
|
|
||||||
|
|
||||||
AM_CONDITIONAL(ENABLE_DEBUG, test "x$enable_debug" = "xyes")
|
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")
|
AM_CONDITIONAL(ENABLE_GRAPHVIZ, test "x$enable_graphviz" = "xyes")
|
||||||
AC_DEFINE(ENABLE_GRAPHVIZ, test "x$enable_graphviz" = "xyes", "whether graphviz is enable")
|
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_CFLAGS)
|
||||||
AC_SUBST(DEPS_LIBS)
|
AC_SUBST(DEPS_LIBS)
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
|
|
39
include/r3.h
39
include/r3.h
|
@ -15,27 +15,40 @@
|
||||||
|
|
||||||
#include "r3_define.h"
|
#include "r3_define.h"
|
||||||
#include "str_array.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(node,i) node->edges[i]->pattern
|
||||||
#define node_edge_pattern_len(node,i) node->edges[i]->pattern_len
|
#define node_edge_pattern_len(node,i) node->edges[i]->pattern_len
|
||||||
|
|
||||||
|
|
||||||
|
struct _root;
|
||||||
struct _edge;
|
struct _edge;
|
||||||
struct _node;
|
struct _node;
|
||||||
struct _route;
|
struct _route;
|
||||||
typedef struct _edge edge;
|
typedef struct _edge edge;
|
||||||
typedef struct _node node;
|
typedef struct _node node;
|
||||||
typedef struct _route route;
|
typedef struct _route route;
|
||||||
|
typedef struct _root root;
|
||||||
|
|
||||||
|
struct _root {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct _node {
|
struct _node {
|
||||||
edge ** edges;
|
edge ** edges;
|
||||||
route ** routes;
|
route ** routes;
|
||||||
int edge_len;
|
edge * parent_edge;
|
||||||
int edge_cap;
|
uint32_t edge_len;
|
||||||
int route_len;
|
uint32_t edge_cap;
|
||||||
int route_cap;
|
uint32_t route_len;
|
||||||
int endpoint;
|
uint32_t route_cap;
|
||||||
|
|
||||||
/** compile-time variables here.... **/
|
/** compile-time variables here.... **/
|
||||||
|
|
||||||
|
@ -50,14 +63,20 @@ struct _node {
|
||||||
*/
|
*/
|
||||||
void * data;
|
void * data;
|
||||||
|
|
||||||
|
uint8_t endpoint;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _edge {
|
struct _edge {
|
||||||
|
/* the child node */
|
||||||
|
node * child;
|
||||||
|
/* the parent node */
|
||||||
|
node * parent;
|
||||||
|
|
||||||
char * pattern;
|
char * pattern;
|
||||||
int pattern_len;
|
int pattern_len;
|
||||||
int opcode;
|
int opcode;
|
||||||
bool has_slug;
|
float score;
|
||||||
node * child;
|
bool has_slug:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -167,6 +186,8 @@ void r3_route_free(route * route);
|
||||||
|
|
||||||
route * r3_tree_match_route(const node *n, match_entry * entry);
|
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_GET 2
|
||||||
#define METHOD_POST 2<<1
|
#define METHOD_POST 2<<1
|
||||||
#define METHOD_PUT 2<<2
|
#define METHOD_PUT 2<<2
|
||||||
|
|
14
src/edge.c
14
src/edge.c
|
@ -30,6 +30,14 @@ edge * r3_edge_create(char * pattern, int pattern_len, node * child) {
|
||||||
e->pattern_len = pattern_len;
|
e->pattern_len = pattern_len;
|
||||||
e->opcode = 0;
|
e->opcode = 0;
|
||||||
e->child = child;
|
e->child = child;
|
||||||
|
e->parent = NULL;
|
||||||
|
|
||||||
|
// update childs parent edge
|
||||||
|
child->parent_edge = e;
|
||||||
|
|
||||||
|
// default stats
|
||||||
|
// e->hits = 0;
|
||||||
|
e->score = 0;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +63,10 @@ node * r3_edge_branch(edge *e, int dl) {
|
||||||
|
|
||||||
// the suffix edge of the leaf
|
// the suffix edge of the leaf
|
||||||
new_child = r3_tree_create(3);
|
new_child = r3_tree_create(3);
|
||||||
s1_len = e->pattern_len - dl;
|
s1_len = e->pattern_len - dl;
|
||||||
e1 = r3_edge_create(zstrndup(s1, s1_len), s1_len, new_child);
|
|
||||||
|
/* 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.
|
// Migrate the child edges to the new edge we just created.
|
||||||
for ( int i = 0 ; i < tmp_edge_len ; i++ ) {
|
for ( int i = 0 ; i < tmp_edge_len ; i++ ) {
|
||||||
|
|
28
src/node.c
28
src/node.c
|
@ -45,6 +45,8 @@ node * r3_tree_create(int cap) {
|
||||||
n->edge_len = 0;
|
n->edge_len = 0;
|
||||||
n->edge_cap = cap;
|
n->edge_cap = cap;
|
||||||
|
|
||||||
|
n->parent_edge = NULL;
|
||||||
|
|
||||||
n->routes = NULL;
|
n->routes = NULL;
|
||||||
n->route_len = 0;
|
n->route_len = 0;
|
||||||
n->route_cap = 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;
|
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) {
|
void r3_node_append_edge(node *n, edge *e) {
|
||||||
if (n->edges == NULL) {
|
if (n->edges == NULL) {
|
||||||
n->edge_cap = 3;
|
n->edge_cap = 3;
|
||||||
|
@ -107,6 +129,8 @@ void r3_node_append_edge(node *n, edge *e) {
|
||||||
n->edges = p;
|
n->edges = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// when append new edge, we update the parent node of the edge.
|
||||||
|
e->parent = n;
|
||||||
n->edges[ n->edge_len++ ] = e;
|
n->edges[ n->edge_len++ ] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,6 +432,8 @@ node * r3_node_create() {
|
||||||
n->edge_len = 0;
|
n->edge_len = 0;
|
||||||
n->edge_cap = 0;
|
n->edge_cap = 0;
|
||||||
|
|
||||||
|
n->parent_edge = NULL;
|
||||||
|
|
||||||
n->routes = NULL;
|
n->routes = NULL;
|
||||||
n->route_len = 0;
|
n->route_len = 0;
|
||||||
n->route_cap = 0;
|
n->route_cap = 0;
|
||||||
|
@ -636,6 +662,8 @@ void r3_tree_dump(node * n, int level) {
|
||||||
print_indent(level + 1);
|
print_indent(level + 1);
|
||||||
printf("|-\"%s\"", e->pattern);
|
printf("|-\"%s\"", e->pattern);
|
||||||
|
|
||||||
|
// printf(" hits:%lld score:%.1f ", e->hits, e->score);
|
||||||
|
printf(" score:%.1f ", e->score);
|
||||||
if (e->opcode ) {
|
if (e->opcode ) {
|
||||||
printf(" opcode:%d", e->opcode);
|
printf(" opcode:%d", e->opcode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,6 +361,34 @@ START_TEST(test_insert_route)
|
||||||
END_TEST
|
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* r3_suite (void) {
|
||||||
Suite *suite = suite_create("blah");
|
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);
|
||||||
tcase_add_test(tcase, test_pcre_patterns_insert_2);
|
tcase_add_test(tcase, test_pcre_patterns_insert_2);
|
||||||
tcase_add_test(tcase, test_pcre_patterns_insert_3);
|
tcase_add_test(tcase, test_pcre_patterns_insert_3);
|
||||||
|
tcase_add_test(tcase, test_feedback);
|
||||||
tcase_set_timeout(tcase, 30);
|
tcase_set_timeout(tcase, 30);
|
||||||
|
|
||||||
suite_add_tcase(suite, tcase);
|
suite_add_tcase(suite, tcase);
|
||||||
|
|
Loading…
Reference in a new issue