mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
MEDIUM: stick-table: make it easier to register extra data types
Some users want to add their own data types to stick tables. We don't want to use a linked list here for performance reasons, so we need to continue to use an indexed array. This patch allows one to reserve a compile-time-defined number of extra data types by setting the new macro STKTABLE_EXTRA_DATA_TYPES to anything greater than zero, keeping in mind that anything larger will slightly inflate the memory consumed by stick tables (not per entry though). Then calling stktable_register_data_store() with the new keyword will either register a new keyword or fail if the desired entry was already taken or the keyword already registered. Note that this patch does not dictate how the data will be used, it only offers the possibility to create new keywords and have an index to reference them in the config and in the tables. The caller will not be able to use stktable_data_cast() and will have to explicitly cast the stable pointers to the expected types. It can be used for experimentation as well.
This commit is contained in:
parent
e12704bfc7
commit
edee1d60b7
@ -83,6 +83,11 @@
|
||||
#define MAX_SESS_STKCTR 3
|
||||
#endif
|
||||
|
||||
// max # of extra stick-table data types that can be registred at runtime
|
||||
#ifndef STKTABLE_EXTRA_DATA_TYPES
|
||||
#define STKTABLE_EXTRA_DATA_TYPES 0
|
||||
#endif
|
||||
|
||||
// max # of loops we can perform around a read() which succeeds.
|
||||
// It's very frequent that the system returns a few TCP segments at a time.
|
||||
#ifndef MAX_READ_POLL_LOOPS
|
||||
|
@ -51,6 +51,7 @@ struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px,
|
||||
struct session *l4, void *l7, unsigned int opt,
|
||||
struct sample_expr *expr, struct sample *smp);
|
||||
int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_type);
|
||||
int stktable_register_data_store(int idx, const char *name, int std_type, int arg_type);
|
||||
int stktable_get_data_type(char *name);
|
||||
struct proxy *find_stktable(const char *name);
|
||||
int stktable_trash_oldest(struct stktable *t, int to_batch);
|
||||
|
@ -60,7 +60,11 @@ enum {
|
||||
STKTABLE_DT_BYTES_IN_RATE,/* bytes rate from client to servers */
|
||||
STKTABLE_DT_BYTES_OUT_CNT,/* cumulated bytes count from servers to client */
|
||||
STKTABLE_DT_BYTES_OUT_RATE,/* bytes rate from servers to client */
|
||||
STKTABLE_DATA_TYPES /* Number of data types, must always be last */
|
||||
STKTABLE_STATIC_DATA_TYPES,/* number of types above */
|
||||
/* up to STKTABLE_EXTRA_DATA_TYPES types may be registered here, always
|
||||
* followed by the number of data types, must always be last.
|
||||
*/
|
||||
STKTABLE_DATA_TYPES = STKTABLE_STATIC_DATA_TYPES + STKTABLE_EXTRA_DATA_TYPES
|
||||
};
|
||||
|
||||
/* The equivalent standard types of the stored data */
|
||||
|
@ -688,7 +688,10 @@ int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_typ
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extra data types processing */
|
||||
/* Extra data types processing : after the last one, some room may remain
|
||||
* before STKTABLE_DATA_TYPES that may be used to register extra data types
|
||||
* at run time.
|
||||
*/
|
||||
struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
|
||||
[STKTABLE_DT_SERVER_ID] = { .name = "server_id", .std_type = STD_T_SINT },
|
||||
[STKTABLE_DT_GPC0] = { .name = "gpc0", .std_type = STD_T_UINT },
|
||||
@ -708,6 +711,36 @@ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
|
||||
[STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
|
||||
};
|
||||
|
||||
/* Registers stick-table extra data type with index <idx>, name <name>, type
|
||||
* <std_type> and arg type <arg_type>. If the index is negative, the next free
|
||||
* index is automatically allocated. The allocated index is returned, or -1 if
|
||||
* no free index was found or <name> was already registered. The <name> is used
|
||||
* directly as a pointer, so if it's not stable, the caller must allocate it.
|
||||
*/
|
||||
int stktable_register_data_store(int idx, const char *name, int std_type, int arg_type)
|
||||
{
|
||||
if (idx < 0) {
|
||||
for (idx = 0; idx < STKTABLE_DATA_TYPES; idx++) {
|
||||
if (!stktable_data_types[idx].name)
|
||||
break;
|
||||
|
||||
if (strcmp(stktable_data_types[idx].name, name) == 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx >= STKTABLE_DATA_TYPES)
|
||||
return -1;
|
||||
|
||||
if (stktable_data_types[idx].name != NULL)
|
||||
return -1;
|
||||
|
||||
stktable_data_types[idx].name = name;
|
||||
stktable_data_types[idx].std_type = std_type;
|
||||
stktable_data_types[idx].arg_type = arg_type;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the data type number for the stktable_data_type whose name is <name>,
|
||||
* or <0 if not found.
|
||||
@ -717,6 +750,8 @@ int stktable_get_data_type(char *name)
|
||||
int type;
|
||||
|
||||
for (type = 0; type < STKTABLE_DATA_TYPES; type++) {
|
||||
if (!stktable_data_types[type].name)
|
||||
continue;
|
||||
if (strcmp(name, stktable_data_types[type].name) == 0)
|
||||
return type;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user