From: Willy Tarreau Date: Sun, 18 Jul 2010 06:04:30 +0000 (+0200) Subject: [MEDIUM] stick-table: make use of generic types for stored data X-Git-Tag: v1.5-dev8~506 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b9c6e053e78c9a42155fdddc3500feb51164836;p=thirdparty%2Fhaproxy.git [MEDIUM] stick-table: make use of generic types for stored data It's a bit cumbersome to have to know all possible storable types from the stats interface. Instead, let's have generic types for all data, which will facilitate their manipulation. --- diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h index 6b80eef45b..e702356fd9 100644 --- a/include/proto/stick_table.h +++ b/include/proto/stick_table.h @@ -50,6 +50,21 @@ int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_t int stktable_get_data_type(char *name); struct proxy *find_stktable(const char *name); +/* return allocation size for standard data type */ +static inline int stktable_type_size(int type) +{ + switch(type) { + case STD_T_SINT: + case STD_T_UINT: + return sizeof(int); + case STD_T_ULL: + return sizeof(unsigned long long); + case STD_T_FRQP: + return sizeof(struct freq_ctr_period); + } + return 0; +} + /* reserve some space for data type , and associate argument at if * not NULL. Returns PE_NONE (0) if OK or an error code among : * - PE_ENUM_OOR if does not exist @@ -85,7 +100,7 @@ static inline int stktable_alloc_data_type(struct stktable *t, int type, const c break; } - t->data_size += stktable_data_types[type].data_length; + t->data_size += stktable_type_size(stktable_data_types[type].std_type); t->data_ofs[type] = -t->data_size; return PE_NONE; } diff --git a/include/types/stick_table.h b/include/types/stick_table.h index a5f47e3edd..4338e59cc2 100644 --- a/include/types/stick_table.h +++ b/include/types/stick_table.h @@ -60,6 +60,14 @@ enum { STKTABLE_DATA_TYPES /* Number of data types, must always be last */ }; +/* The equivalent standard types of the stored data */ +enum { + STD_T_SINT = 0, /* data is of type signed int */ + STD_T_UINT, /* data is of type unsigned int */ + STD_T_ULL, /* data is of type unsigned long long */ + STD_T_FRQP, /* data is of type freq_ctr_period */ +}; + /* The types of optional arguments to stored data */ enum { ARG_T_NONE = 0, /* data type takes no argument (default) */ @@ -69,6 +77,13 @@ enum { /* stick_table extra data. This is mainly used for casting or size computation */ union stktable_data { + /* standard types for easy casting */ + int std_t_sint; + unsigned int std_t_uint; + unsigned long long std_t_ull; + struct freq_ctr_period std_t_frqp; + + /* types of each storable data */ int server_id; unsigned int gpc0; unsigned int conn_cnt; @@ -89,7 +104,7 @@ union stktable_data { /* known data types */ struct stktable_data_type { const char *name; /* name of the data type */ - int data_length; /* length of this type, or 0 if variable (eg: string) */ + int std_type; /* standard type we can use for this data, STD_T_* */ int arg_type; /* type of optional argument, ARG_T_* */ }; diff --git a/src/dumpstats.c b/src/dumpstats.c index 32ca1b9607..44bde41c4d 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -2968,31 +2968,21 @@ int stats_dump_table_to_buffer(struct session *s, struct buffer *rep) ptr = stktable_data_ptr(&s->data_ctx.table.proxy->table, s->data_ctx.table.entry, dt); - switch (dt) { - /* all entries using the same type can be folded */ - case STKTABLE_DT_SERVER_ID: - case STKTABLE_DT_GPC0: - case STKTABLE_DT_CONN_CNT: - case STKTABLE_DT_CONN_CUR: - case STKTABLE_DT_SESS_CNT: - case STKTABLE_DT_HTTP_REQ_CNT: - case STKTABLE_DT_HTTP_ERR_CNT: - chunk_printf(&msg, "%u", stktable_data_cast(ptr, server_id)); + switch (stktable_data_types[dt].std_type) { + case STD_T_SINT: + chunk_printf(&msg, "%d", stktable_data_cast(ptr, std_t_sint)); break; - case STKTABLE_DT_CONN_RATE: - case STKTABLE_DT_SESS_RATE: - case STKTABLE_DT_HTTP_REQ_RATE: - case STKTABLE_DT_HTTP_ERR_RATE: - case STKTABLE_DT_BYTES_IN_RATE: - case STKTABLE_DT_BYTES_OUT_RATE: + case STD_T_UINT: + chunk_printf(&msg, "%u", stktable_data_cast(ptr, std_t_uint)); + break; + case STD_T_ULL: + chunk_printf(&msg, "%lld", stktable_data_cast(ptr, std_t_ull)); + break; + case STD_T_FRQP: chunk_printf(&msg, "%d", - read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate), + read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp), s->data_ctx.table.proxy->table.data_arg[dt].u)); break; - case STKTABLE_DT_BYTES_IN_CNT: - case STKTABLE_DT_BYTES_OUT_CNT: - chunk_printf(&msg, "%lld", stktable_data_cast(ptr, bytes_in_cnt)); - break; } } chunk_printf(&msg, "\n"); diff --git a/src/stick_table.c b/src/stick_table.c index 46d5e1e391..ccfd7b5792 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -545,21 +545,21 @@ int stktable_compatible_pattern(struct pattern_expr *expr, unsigned long table_t /* Extra data types processing */ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = { - [STKTABLE_DT_SERVER_ID] = { .name = "server_id", .data_length = stktable_data_size(server_id) }, - [STKTABLE_DT_GPC0] = { .name = "gpc0", .data_length = stktable_data_size(gpc0) }, - [STKTABLE_DT_CONN_CNT] = { .name = "conn_cnt", .data_length = stktable_data_size(conn_cnt) }, - [STKTABLE_DT_CONN_RATE] = { .name = "conn_rate", .data_length = stktable_data_size(conn_rate), .arg_type = ARG_T_DELAY }, - [STKTABLE_DT_CONN_CUR] = { .name = "conn_cur", .data_length = stktable_data_size(conn_cur) }, - [STKTABLE_DT_SESS_CNT] = { .name = "sess_cnt", .data_length = stktable_data_size(sess_cnt) }, - [STKTABLE_DT_SESS_RATE] = { .name = "sess_rate", .data_length = stktable_data_size(sess_rate), .arg_type = ARG_T_DELAY }, - [STKTABLE_DT_HTTP_REQ_CNT] = { .name = "http_req_cnt", .data_length = stktable_data_size(http_req_cnt) }, - [STKTABLE_DT_HTTP_REQ_RATE] = { .name = "http_req_rate", .data_length = stktable_data_size(http_req_rate), .arg_type = ARG_T_DELAY }, - [STKTABLE_DT_HTTP_ERR_CNT] = { .name = "http_err_cnt", .data_length = stktable_data_size(http_err_cnt) }, - [STKTABLE_DT_HTTP_ERR_RATE] = { .name = "http_err_rate", .data_length = stktable_data_size(http_err_rate), .arg_type = ARG_T_DELAY }, - [STKTABLE_DT_BYTES_IN_CNT] = { .name = "bytes_in_cnt", .data_length = stktable_data_size(bytes_in_cnt) }, - [STKTABLE_DT_BYTES_IN_RATE] = { .name = "bytes_in_rate", .data_length = stktable_data_size(bytes_in_rate), .arg_type = ARG_T_DELAY }, - [STKTABLE_DT_BYTES_OUT_CNT] = { .name = "bytes_out_cnt", .data_length = stktable_data_size(bytes_out_cnt) }, - [STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate",.data_length = stktable_data_size(bytes_out_rate), .arg_type = ARG_T_DELAY }, + [STKTABLE_DT_SERVER_ID] = { .name = "server_id", .std_type = STD_T_SINT }, + [STKTABLE_DT_GPC0] = { .name = "gpc0", .std_type = STD_T_UINT }, + [STKTABLE_DT_CONN_CNT] = { .name = "conn_cnt", .std_type = STD_T_UINT }, + [STKTABLE_DT_CONN_RATE] = { .name = "conn_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, + [STKTABLE_DT_CONN_CUR] = { .name = "conn_cur", .std_type = STD_T_UINT }, + [STKTABLE_DT_SESS_CNT] = { .name = "sess_cnt", .std_type = STD_T_UINT }, + [STKTABLE_DT_SESS_RATE] = { .name = "sess_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, + [STKTABLE_DT_HTTP_REQ_CNT] = { .name = "http_req_cnt", .std_type = STD_T_UINT }, + [STKTABLE_DT_HTTP_REQ_RATE] = { .name = "http_req_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, + [STKTABLE_DT_HTTP_ERR_CNT] = { .name = "http_err_cnt", .std_type = STD_T_UINT }, + [STKTABLE_DT_HTTP_ERR_RATE] = { .name = "http_err_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, + [STKTABLE_DT_BYTES_IN_CNT] = { .name = "bytes_in_cnt", .std_type = STD_T_ULL }, + [STKTABLE_DT_BYTES_IN_RATE] = { .name = "bytes_in_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, + [STKTABLE_DT_BYTES_OUT_CNT] = { .name = "bytes_out_cnt", .std_type = STD_T_ULL }, + [STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, }; /*