Compare commits
34 commits
2.0
...
feature/th
Author | SHA1 | Date | |
---|---|---|---|
|
f746030d3f | ||
|
2a25cfdf01 | ||
|
56bda02997 | ||
|
5d376a9592 | ||
|
7074e89fd0 | ||
|
def79a810b | ||
|
9c6902ed57 | ||
|
e27740688a | ||
|
5d4b0dc3c9 | ||
|
e877dc7f0d | ||
|
0f5ebed73c | ||
|
0b499c9158 | ||
|
76e4b15787 | ||
|
546fcb14af | ||
|
faaaeb5f90 | ||
|
8471f42579 | ||
|
3cbffb645c | ||
|
1563bd5a78 | ||
|
adbe71d336 | ||
|
d73a3aa89a | ||
|
a4378fdaf2 | ||
|
3121937da5 | ||
|
c421bea11f | ||
|
5ada611182 | ||
|
ba270b5948 | ||
|
24aaa881b1 | ||
|
595dadba15 | ||
|
d6b2e52567 | ||
|
2b331ecc8f | ||
|
21a8c0c891 | ||
|
a5035ad962 | ||
|
3500e19316 | ||
|
58b74b9126 | ||
|
f8154b23e9 |
17 changed files with 765 additions and 51 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.
|
121
config.h.in
Normal file
121
config.h.in
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/* 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 you have the <pthread.h> header file. */
|
||||||
|
#undef HAVE_PTHREAD_H
|
||||||
|
|
||||||
|
/* 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 pthread.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([
|
||||||
|
|
35
include/r3.h
35
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
|
||||||
|
|
48
include/r3_queue.h
Normal file
48
include/r3_queue.h
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* r3_queue.h
|
||||||
|
* Copyright (C) 2014 c9s <c9s@c9smba.local>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef R3_QUEUE_H
|
||||||
|
#define R3_QUEUE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct _queue;
|
||||||
|
struct _queue_node;
|
||||||
|
typedef struct _queue_node queue_node;
|
||||||
|
typedef struct _queue queue;
|
||||||
|
|
||||||
|
struct _queue_node {
|
||||||
|
void *data;
|
||||||
|
queue * next;
|
||||||
|
};
|
||||||
|
// typedef struct _queue_node queue_node;
|
||||||
|
|
||||||
|
struct _queue {
|
||||||
|
queue_node * first;
|
||||||
|
queue_node * last;
|
||||||
|
};
|
||||||
|
|
||||||
|
// create and return the queue
|
||||||
|
queue * queue_new(void);
|
||||||
|
|
||||||
|
// destory the queue (free all the memory associate with the que even the data)
|
||||||
|
void queue_free(queue * que);
|
||||||
|
|
||||||
|
|
||||||
|
// queue_push the data into queue
|
||||||
|
// data is expected to a pointer to a heap allocated memory
|
||||||
|
int queue_push(queue * que, void * data);
|
||||||
|
|
||||||
|
// return the data from the que (FIFO)
|
||||||
|
// and free up all the internally allocated memory
|
||||||
|
// but the user have to free the returning data pointer
|
||||||
|
void * queue_pop(queue * que);
|
||||||
|
|
||||||
|
#endif /* !R3_QUEUE_H */
|
26
include/r3_workers.h
Normal file
26
include/r3_workers.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* r3_workers.h
|
||||||
|
* Copyright (C) 2014 c9s <c9s@c9smba.local>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef R3_WORKERS_H
|
||||||
|
#define R3_WORKERS_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int thread_id;
|
||||||
|
node * matched_node;
|
||||||
|
} feedback_payload;
|
||||||
|
|
||||||
|
void r3_feedback_worker_init(pthread_t * t, feedback_payload * data);
|
||||||
|
|
||||||
|
void r3_worker_cancel(pthread_t t);
|
||||||
|
|
||||||
|
void r3_worker_exit();
|
||||||
|
|
||||||
|
#endif /* !R3_WORKERS_H */
|
|
@ -1,10 +1,10 @@
|
||||||
lib_LTLIBRARIES = libr3.la
|
lib_LTLIBRARIES = libr3.la
|
||||||
# lib_LIBRARIES = libr3.a
|
# lib_LIBRARIES = libr3.a
|
||||||
libr3_la_SOURCES = node.c edge.c str.c token.c zmalloc.c
|
libr3_la_SOURCES = node.c edge.c str.c token.c zmalloc.c workers.c queue.c
|
||||||
# libr3_la_LDFLAGS = -export-symbols-regex '^r3_|^match_'
|
# libr3_la_LDFLAGS = -export-symbols-regex '^r3_|^match_'
|
||||||
|
|
||||||
libr3_la_LIBADD=$(DEPS_LIBS)
|
libr3_la_LIBADD=$(DEPS_LIBS)
|
||||||
AM_CFLAGS=$(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include -Wall -std=c99
|
AM_CFLAGS=$(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include -Wall -std=c99 -lpthread
|
||||||
|
|
||||||
if USE_JEMALLOC
|
if USE_JEMALLOC
|
||||||
AM_CFLAGS += -ljemalloc
|
AM_CFLAGS += -ljemalloc
|
||||||
|
|
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->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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +64,8 @@ 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;
|
||||||
|
|
||||||
|
/* create the parent edge of new child */
|
||||||
e1 = r3_edge_create(zstrndup(s1, s1_len), s1_len, 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.
|
||||||
|
|
27
src/node.c
27
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,25 @@ 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.01;
|
||||||
|
|
||||||
|
if (e->score > 10) {
|
||||||
|
for (int i = 0 ; i < p->edge_len ; i++ ) {
|
||||||
|
if ( p->edges[i]->score > 0 ) {
|
||||||
|
p->edges[i]->score /= 10.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 +128,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 +431,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 +661,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);
|
||||||
}
|
}
|
||||||
|
|
128
src/queue.c
Normal file
128
src/queue.c
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
/*
|
||||||
|
* queue.c
|
||||||
|
* Copyright (C) 2014 c9s <c9s@c9smba.local>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include "r3_queue.h"
|
||||||
|
#include "zmalloc.h"
|
||||||
|
|
||||||
|
|
||||||
|
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and return a new queue
|
||||||
|
**/
|
||||||
|
queue * queue_new()
|
||||||
|
{
|
||||||
|
queue * q = zmalloc(sizeof(queue));
|
||||||
|
if(q == NULL) {
|
||||||
|
fprintf(stderr, "Malloc failed creating the que\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
q->first = NULL;
|
||||||
|
q->last = NULL;
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void queue_free(queue * que)
|
||||||
|
{
|
||||||
|
if(que == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if(que->first == NULL) {
|
||||||
|
// ("que->first == NULL .... \n");
|
||||||
|
zfree(que);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ("que is there lets try to free it...\n");
|
||||||
|
|
||||||
|
queue_node * qn = que->first;
|
||||||
|
|
||||||
|
while(qn != NULL) {
|
||||||
|
// freeing the data coz it's on the heap and no one to free it
|
||||||
|
// except for this one
|
||||||
|
// ("freeing : %s\n", (char *)qn->data);
|
||||||
|
zfree(qn->data);
|
||||||
|
queue_node *tmp = qn->next;
|
||||||
|
zfree(qn);
|
||||||
|
qn = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
zfree(que);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* que is a queue pointer
|
||||||
|
* data is a heap allocated memory pointer
|
||||||
|
*/
|
||||||
|
int queue_push(queue * que, void * data)
|
||||||
|
{
|
||||||
|
queue_node * new_node = zmalloc(sizeof(queue_node));
|
||||||
|
if (new_node == NULL) {
|
||||||
|
fprintf(stderr, "Malloc failed creating a queue_node\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// assumming data is in heap
|
||||||
|
new_node->data = data;
|
||||||
|
new_node->next = NULL;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if (que->first == NULL) {
|
||||||
|
// new que
|
||||||
|
que->first = new_node;
|
||||||
|
que->last = new_node;
|
||||||
|
} else {
|
||||||
|
que->last->next = new_node;
|
||||||
|
que->last = new_node;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * queue_pop(queue * que)
|
||||||
|
{
|
||||||
|
// print("Entered to queue_pop\n");
|
||||||
|
if (que == NULL) {
|
||||||
|
// print("que is null exiting...\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
if (que->first == NULL) {
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
// print("que->first is null exiting...\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * data;
|
||||||
|
queue_node * qn = que->first;
|
||||||
|
if (que->first == que->last) {
|
||||||
|
que->first = NULL;
|
||||||
|
que->last = NULL;
|
||||||
|
} else {
|
||||||
|
que->first = qn->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = qn->data;
|
||||||
|
|
||||||
|
// print("Freeing qn@ %p", qn);
|
||||||
|
zfree(qn);
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
// print("Exiting queue_pop\n");
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
41
src/workers.c
Normal file
41
src/workers.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* workers.c
|
||||||
|
* Copyright (C) 2014 c9s <c9s@c9smba.local>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#include "r3.h"
|
||||||
|
#include "r3_workers.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
void *r3_feedback_worker(void * data) {
|
||||||
|
feedback_payload * payload = (feedback_payload*) data; // pointer cast
|
||||||
|
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void r3_feedback_worker_init(pthread_t * t, feedback_payload * data) {
|
||||||
|
int rc;
|
||||||
|
// pthread_t worker_thread;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
rc = pthread_create(t, &attr, r3_feedback_worker, (void*) data);
|
||||||
|
|
||||||
|
// if the pthread is created, we may free the attr
|
||||||
|
pthread_attr_destroy(&attr);
|
||||||
|
|
||||||
|
// rc = pthread_join(t, &status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void r3_worker_cancel(pthread_t t) {
|
||||||
|
pthread_cancel(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void r3_worker_exit() {
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# endif
|
# endif
|
||||||
TESTS = check_tree
|
TESTS = check_tree
|
||||||
AM_CFLAGS = -ggdb $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@
|
AM_CFLAGS = -ggdb $(DEPS_CFLAGS) -I$(top_builddir) -I$(top_builddir)/include @CHECK_CFLAGS@
|
||||||
AM_LDFLAGS = $(DEPS_LIBS) -L$(top_builddir)/src -lr3 @CHECK_LIBS@
|
AM_LDFLAGS = $(DEPS_LIBS) -L$(top_builddir)/src -lpthread -lr3 @CHECK_LIBS@
|
||||||
|
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
|
@ -43,6 +43,11 @@ check_tree_SOURCES = check_tree.c
|
||||||
TESTS += check_slug
|
TESTS += check_slug
|
||||||
check_slug_SOURCES = check_slug.c
|
check_slug_SOURCES = check_slug.c
|
||||||
|
|
||||||
|
TESTS += check_worker
|
||||||
|
check_worker_SOURCES = check_worker.c
|
||||||
|
|
||||||
|
TESTS += check_queue
|
||||||
|
check_queue_SOURCES = check_queue.c
|
||||||
|
|
||||||
check_PROGRAMS = $(TESTS)
|
check_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
|
126
tests/check_queue.c
Normal file
126
tests/check_queue.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* check_queue.c
|
||||||
|
* Copyright (C) 2014 c9s <c9s@c9smba.local>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#include "r3_queue.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <check.h>
|
||||||
|
|
||||||
|
#include "r3.h"
|
||||||
|
#include "zmalloc.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define number_of_threads 6
|
||||||
|
#define number_of_threads_d 5
|
||||||
|
#define number_of_iters 1000
|
||||||
|
|
||||||
|
struct _stru {
|
||||||
|
int number;
|
||||||
|
int thread_no;
|
||||||
|
queue * q;
|
||||||
|
};
|
||||||
|
|
||||||
|
void * producer_thread(void * arg)
|
||||||
|
{
|
||||||
|
struct _stru * args = (struct _stru *) arg;
|
||||||
|
int number = args->number;
|
||||||
|
//int th_number = args->thread_no;
|
||||||
|
queue * q = args->q;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
srand(time(NULL));
|
||||||
|
for(i = 0; i < number; i++) {
|
||||||
|
char * message = zmalloc(16);
|
||||||
|
snprintf(message, 15, "rand: %d", rand());
|
||||||
|
queue_push(q, (void *)message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void * consumer_thread(void * args)
|
||||||
|
{
|
||||||
|
queue * q = (queue *) args;
|
||||||
|
void * data;
|
||||||
|
while((data = queue_pop(q)) != NULL) {
|
||||||
|
char * string = (char *)data;
|
||||||
|
zfree(data);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST (test_queue)
|
||||||
|
{
|
||||||
|
queue * q = queue_new();
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 100 ; i++ ) {
|
||||||
|
queue_push(q, (void*) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 100 ; i++ ) {
|
||||||
|
int v = (int) queue_pop(q);
|
||||||
|
ck_assert_int_eq(i, v);
|
||||||
|
}
|
||||||
|
queue_free(q);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_queue_threads)
|
||||||
|
{
|
||||||
|
queue * q = queue_new();
|
||||||
|
pthread_t threads[number_of_threads];
|
||||||
|
pthread_t thread_d[number_of_threads_d];
|
||||||
|
|
||||||
|
int i;
|
||||||
|
struct _stru arg[number_of_threads];
|
||||||
|
for(i = 0; i < number_of_threads; i++) {
|
||||||
|
arg[i].number = number_of_iters;
|
||||||
|
arg[i].thread_no = i;
|
||||||
|
arg[i].q = q;
|
||||||
|
pthread_create(threads+i, NULL, producer_thread, (void *)&arg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < number_of_threads_d; i++) {
|
||||||
|
pthread_create(thread_d+i, NULL, consumer_thread, (void *)q);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < number_of_threads; i++) {
|
||||||
|
pthread_join(*(threads+i), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < number_of_threads_d; i++) {
|
||||||
|
pthread_join(*(thread_d+i), NULL);
|
||||||
|
}
|
||||||
|
queue_free(q);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Suite* r3_suite (void) {
|
||||||
|
Suite *suite = suite_create("queue");
|
||||||
|
TCase *tcase = tcase_create("queue_test");
|
||||||
|
tcase_add_test(tcase, test_queue_threads);
|
||||||
|
tcase_add_test(tcase, test_queue);
|
||||||
|
tcase_set_timeout(tcase, 30);
|
||||||
|
suite_add_tcase(suite, tcase);
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
int number_failed;
|
||||||
|
Suite *suite = r3_suite();
|
||||||
|
SRunner *runner = srunner_create(suite);
|
||||||
|
srunner_run_all(runner, CK_VERBOSE);
|
||||||
|
number_failed = srunner_ntests_failed(runner);
|
||||||
|
srunner_free(runner);
|
||||||
|
return number_failed;
|
||||||
|
}
|
|
@ -125,7 +125,7 @@ int main (int argc, char *argv[]) {
|
||||||
int number_failed;
|
int number_failed;
|
||||||
Suite *suite = r3_suite();
|
Suite *suite = r3_suite();
|
||||||
SRunner *runner = srunner_create(suite);
|
SRunner *runner = srunner_create(suite);
|
||||||
srunner_run_all(runner, CK_NORMAL);
|
srunner_run_all(runner, CK_VERBOSE);
|
||||||
number_failed = srunner_ntests_failed(runner);
|
number_failed = srunner_ntests_failed(runner);
|
||||||
srunner_free(runner);
|
srunner_free(runner);
|
||||||
return number_failed;
|
return number_failed;
|
||||||
|
|
|
@ -361,8 +361,36 @@ 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("route tests");
|
||||||
|
|
||||||
TCase *tcase = tcase_create("testcase");
|
TCase *tcase = tcase_create("testcase");
|
||||||
tcase_set_timeout(tcase, 30);
|
tcase_set_timeout(tcase, 30);
|
||||||
|
@ -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);
|
||||||
|
@ -390,7 +419,7 @@ int main (int argc, char *argv[]) {
|
||||||
int number_failed;
|
int number_failed;
|
||||||
Suite *suite = r3_suite();
|
Suite *suite = r3_suite();
|
||||||
SRunner *runner = srunner_create(suite);
|
SRunner *runner = srunner_create(suite);
|
||||||
srunner_run_all(runner, CK_NORMAL);
|
srunner_run_all(runner, CK_VERBOSE);
|
||||||
number_failed = srunner_ntests_failed(runner);
|
number_failed = srunner_ntests_failed(runner);
|
||||||
srunner_free(runner);
|
srunner_free(runner);
|
||||||
return number_failed;
|
return number_failed;
|
||||||
|
|
68
tests/check_worker.c
Normal file
68
tests/check_worker.c
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* check_worker.c
|
||||||
|
* Copyright (C) 2014 c9s <c9s@c9smba.local>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the MIT license.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <check.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "r3.h"
|
||||||
|
#include "r3_str.h"
|
||||||
|
#include "r3_workers.h"
|
||||||
|
#include "str_array.h"
|
||||||
|
#include "bench.h"
|
||||||
|
|
||||||
|
START_TEST (test_feedback_worker)
|
||||||
|
{
|
||||||
|
node * n = r3_tree_create(1);
|
||||||
|
|
||||||
|
|
||||||
|
r3_tree_insert_path(n, "/foo/bar/baz", NULL);
|
||||||
|
r3_tree_insert_path(n, "/foo/bar/qux", NULL);
|
||||||
|
r3_tree_insert_path(n, "/foo/bar/quux", NULL);
|
||||||
|
r3_tree_insert_path(n, "/foo/bar/corge", NULL);
|
||||||
|
r3_tree_insert_path(n, "/foo/bar/grault", NULL);
|
||||||
|
r3_tree_insert_path(n, "/garply/grault/foo", NULL);
|
||||||
|
r3_tree_insert_path(n, "/garply/grault/bar", NULL);
|
||||||
|
r3_tree_compile(n);
|
||||||
|
|
||||||
|
giant_lock *tl = r3_giant_lock_create(n);
|
||||||
|
|
||||||
|
node * matched;
|
||||||
|
matched = r3_tree_matchl_ts(n, "/garply/grault/foo", strlen("/garply/grault/foo"), NULL); // thread-safe
|
||||||
|
|
||||||
|
|
||||||
|
r3_feedback_worker_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
feedback_payload payload;
|
||||||
|
payload.matched_node = matched;
|
||||||
|
r3_feedback_worker_init(&payload);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
r3_tree_free(n);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
Suite* r3_suite (void) {
|
||||||
|
Suite *suite = suite_create("Worker Test");
|
||||||
|
TCase *tcase = tcase_create("worker test");
|
||||||
|
tcase_add_test(tcase, test_feedback_worker);
|
||||||
|
suite_add_tcase(suite, tcase);
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[]) {
|
||||||
|
int number_failed;
|
||||||
|
Suite *suite = r3_suite();
|
||||||
|
SRunner *runner = srunner_create(suite);
|
||||||
|
srunner_run_all(runner, CK_NORMAL);
|
||||||
|
number_failed = srunner_ntests_failed(runner);
|
||||||
|
srunner_free(runner);
|
||||||
|
return number_failed;
|
||||||
|
}
|
Loading…
Reference in a new issue