From ca6f7e1de911f557aea95996ee0de4a5e781d1b7 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 5 Dec 2016 13:03:09 +0000 Subject: [Rework] Use hash tables for symbols options --- src/libmime/filter.c | 64 ++++++++++++++++++++++++++---------------------- src/libmime/filter.h | 6 ++--- src/libserver/protocol.c | 22 ++++++++++------- src/libserver/task.c | 11 ++++++--- src/lua/lua_task.c | 13 +++++----- 5 files changed, 65 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/libmime/filter.c b/src/libmime/filter.c index e3ee3cb63..baeff9fb9 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -75,11 +75,12 @@ insert_metric_result (struct rspamd_task *task, struct metric *metric, const gchar *symbol, double flag, - GList * opts, + const gchar *opt, gboolean single) { struct metric_result *metric_res; struct symbol *s; + char *opt_cpy; gdouble w, *gr_score = NULL; struct rspamd_symbol_def *sdef; struct rspamd_symbols_group *gr = NULL; @@ -142,19 +143,24 @@ insert_metric_result (struct rspamd_task *task, */ single = TRUE; } - if (s->options && opts && opts != s->options && - !(sdef && (sdef->flags & RSPAMD_SYMBOL_FLAG_ONEPARAM))) { - /* Append new options */ - s->options = g_list_concat (s->options, g_list_copy (opts)); - /* - * Note that there is no need to add new destructor of GList as elements of appended - * GList are used directly, so just free initial GList - */ - } - else if (opts) { - s->options = g_list_copy (opts); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_list_free, s->options); + if (opt) { + if (s->options && !(sdef && + (sdef->flags & RSPAMD_SYMBOL_FLAG_ONEPARAM))) { + /* Append new options */ + if (!g_hash_table_lookup (s->options, opt)) { + opt_cpy = rspamd_mempool_strdup (task->task_pool, opt); + g_hash_table_insert (s->options, opt_cpy, opt_cpy); + } + } + else { + s->options = g_hash_table_new (rspamd_strcase_hash, + rspamd_strcase_equal); + rspamd_mempool_add_destructor (task->task_pool, + (rspamd_mempool_destruct_t)g_hash_table_unref, + s->options); + opt_cpy = rspamd_mempool_strdup (task->task_pool, opt); + g_hash_table_insert (s->options, opt_cpy, opt_cpy); + } } if (!single) { /* Handle grow factor */ @@ -190,10 +196,14 @@ insert_metric_result (struct rspamd_task *task, s->def = sdef; metric_res->score += w; - if (opts) { - s->options = g_list_copy (opts); + if (opt) { + s->options = g_hash_table_new (rspamd_strcase_hash, + rspamd_strcase_equal); rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_list_free, s->options); + (rspamd_mempool_destruct_t)g_hash_table_unref, + s->options); + opt_cpy = rspamd_mempool_strdup (task->task_pool, opt); + g_hash_table_insert (s->options, opt_cpy, opt_cpy); } else { s->options = NULL; @@ -201,6 +211,7 @@ insert_metric_result (struct rspamd_task *task, g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s); } + msg_debug ("symbol %s, score %.2f, metric %s, factor: %f", symbol, s->score, @@ -212,7 +223,7 @@ static void insert_result_common (struct rspamd_task *task, const gchar *symbol, double flag, - GList * opts, + const gchar *opt, gboolean single) { struct metric *metric; @@ -224,7 +235,7 @@ insert_result_common (struct rspamd_task *task, while (cur) { metric = cur->data; - insert_metric_result (task, metric, symbol, flag, opts, single); + insert_metric_result (task, metric, symbol, flag, opt, single); cur = g_list_next (cur); } } @@ -234,7 +245,7 @@ insert_result_common (struct rspamd_task *task, task->cfg->default_metric, symbol, flag, - opts, + opt, single); } @@ -242,11 +253,6 @@ insert_result_common (struct rspamd_task *task, if (task->cfg->cache) { rspamd_symbols_cache_inc_frequency (task->cfg->cache, symbol); } - - if (opts != NULL) { - /* XXX: it is not wise to destroy them here */ - g_list_free (opts); - } } /* Insert result that may be increased on next insertions */ @@ -254,9 +260,9 @@ void rspamd_task_insert_result (struct rspamd_task *task, const gchar *symbol, double flag, - GList * opts) + const gchar *opt) { - insert_result_common (task, symbol, flag, opts, task->cfg->one_shot_mode); + insert_result_common (task, symbol, flag, opt, task->cfg->one_shot_mode); } /* Insert result as a single option */ @@ -264,9 +270,9 @@ void rspamd_task_insert_result_single (struct rspamd_task *task, const gchar *symbol, double flag, - GList * opts) + const gchar *opt) { - insert_result_common (task, symbol, flag, opts, TRUE); + insert_result_common (task, symbol, flag, opt, TRUE); } gboolean diff --git a/src/libmime/filter.h b/src/libmime/filter.h index 6c61f5d6f..99e9c78ae 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -19,7 +19,7 @@ struct rspamd_classifier_config; */ struct symbol { double score; /**< symbol's score */ - GList *options; /**< list of symbol's options */ + GHashTable *options; /**< list of symbol's options */ const gchar *name; struct rspamd_symbol_def *def; /**< symbol configuration */ }; @@ -57,7 +57,7 @@ struct metric_result * rspamd_create_metric_result (struct rspamd_task *task, void rspamd_task_insert_result (struct rspamd_task *task, const gchar *symbol, double flag, - GList *opts); + const gchar *opts); /** * Insert a single result to task @@ -70,7 +70,7 @@ void rspamd_task_insert_result (struct rspamd_task *task, void rspamd_task_insert_result_single (struct rspamd_task *task, const gchar *symbol, double flag, - GList *opts); + const gchar *opts); /** * Default consolidation function for metric, it get all symbols and multiply symbol diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index f33422dfe..ace286dbf 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -804,17 +804,21 @@ make_rewritten_subject (struct metric *metric, struct rspamd_task *task) } static ucl_object_t * -rspamd_str_list_ucl (GList *str_list) +rspamd_str_hash_ucl (GHashTable *ht) { + GHashTableIter it; + gpointer k, v; ucl_object_t *top = NULL, *obj; - GList *cur; top = ucl_object_typed_new (UCL_ARRAY); - cur = str_list; - while (cur) { - obj = ucl_object_fromstring (cur->data); - ucl_array_append (top, obj); - cur = g_list_next (cur); + + if (ht) { + g_hash_table_iter_init (&it, ht); + + while (g_hash_table_iter_next (&it, &k, &v)) { + obj = ucl_object_fromstring ((const char *)v); + ucl_array_append (top, obj); + } } return top; @@ -841,8 +845,8 @@ rspamd_metric_symbol_ucl (struct rspamd_task *task, struct metric *m, description), "description", 0, false); } if (sym->options != NULL) { - ucl_object_insert_key (obj, rspamd_str_list_ucl ( - sym->options), "options", 0, false); + ucl_object_insert_key (obj, rspamd_str_hash_ucl (sym->options), + "options", 0, false); } return obj; diff --git a/src/libserver/task.c b/src/libserver/task.c index b9fca4d4a..6cf7532fd 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -1043,14 +1043,17 @@ rspamd_task_log_metric_res (struct rspamd_task *task, } if (lf->flags & RSPAMD_LOG_FLAG_SYMBOLS_PARAMS) { - GList *cur; + GHashTableIter it; + gpointer k, v; rspamd_printf_fstring (&symbuf, "{"); - j = 0; + g_hash_table_iter_init (&it, sym->options); + + while (g_hash_table_iter_next (&it, &k, &v)) { + const char *opt = v; - for (cur = sym->options; cur != NULL; cur = g_list_next (cur)) { - rspamd_printf_fstring (&symbuf, "%s;", cur->data); + rspamd_printf_fstring (&symbuf, "%s;", opt); if (j >= max_log_elts) { rspamd_printf_fstring (&symbuf, "...;"); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index b43cbfeb5..8f28bb97b 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -2322,7 +2322,6 @@ lua_push_symbol_result (lua_State *L, struct metric_result *metric_res; struct symbol *s; gint j; - GList *opt; metric_res = g_hash_table_lookup (task->results, metric->name); if (metric_res) { @@ -2348,14 +2347,16 @@ lua_push_symbol_result (lua_State *L, } if (s->options) { - opt = s->options; + GHashTableIter it; + gpointer k, v; + lua_pushstring (L, "options"); - lua_newtable (L); + lua_createtable (L, g_hash_table_size (s->options), 0); + g_hash_table_iter_init (&it, s->options); - while (opt) { - lua_pushstring (L, opt->data); + while (g_hash_table_iter_next (&it, &k, &v)) { + lua_pushstring (L, (const char*)v); lua_rawseti (L, -2, j++); - opt = g_list_next (opt); } lua_settable (L, -3); -- cgit v1.2.3