]> source.dussan.org Git - rspamd.git/commitdiff
[Rework] Use hash tables for symbols options
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 5 Dec 2016 13:03:09 +0000 (13:03 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 5 Dec 2016 13:03:09 +0000 (13:03 +0000)
src/libmime/filter.c
src/libmime/filter.h
src/libserver/protocol.c
src/libserver/task.c
src/lua/lua_task.c

index e3ee3cb631636c29fb773c586cdc9979761ba9bc..baeff9fb9ffb887ec695f521d98a2f2ffae6bb3c 100644 (file)
@@ -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
index 6c61f5d6f10e75130c28696cb795d0e7e1b9fe0a..99e9c78aea04c410e113dfc2deba33f72936a042 100644 (file)
@@ -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
index f33422dfe50b469a214aae378e0c1c93a1395a0a..ace286dbf3a2e8e943d5e0f6a5039331a504d4c5 100644 (file)
@@ -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;
index b9fca4d4af10fba6c07ef72704cd629fd34292e7..6cf7532fd566889146b999eb6fb493dc30d5c105 100644 (file)
@@ -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, "...;");
index b43cbfeb57127a541b961624365a61233b43a0bb..8f28bb97bf5b719a013a5814946828f2f32d1d75 100644 (file)
@@ -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);