]> source.dussan.org Git - rspamd.git/commitdiff
* Improve performance of settings lookup
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 30 Jun 2011 14:32:11 +0000 (18:32 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 30 Jun 2011 14:32:11 +0000 (18:32 +0400)
src/filter.c
src/filter.h
src/protocol.c
src/settings.c
src/settings.h
src/smtp_utils.c

index b625e4c722e6d22f47863023b491e74448b3af07..b48bf64ba25c83d7d5b3fe94423fb57388bf4445 100644 (file)
@@ -67,6 +67,9 @@ insert_metric_result (struct worker_task *task, struct metric *metric, const gch
                metric_res->metric = metric;
                metric_res->grow_factor = 0;
                metric_res->score = 0;
+               metric_res->domain_settings = NULL;
+               metric_res->user_settings = NULL;
+               apply_metric_settings (task, metric, metric_res);
                g_hash_table_insert (task->results, (gpointer) metric->name, metric_res);
        }
        
@@ -238,7 +241,7 @@ check_metric_is_spam (struct worker_task *task, struct metric *metric)
 
        res = g_hash_table_lookup (task->results, metric->name);
        if (res) {
-               if (!check_metric_settings (task, metric, &ms, &rs)) {
+               if (!check_metric_settings (res, &ms, &rs)) {
                        ms = metric->required_score;
                }
                return res->score >= ms;
@@ -706,7 +709,7 @@ insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data
 
        rspamd_snprintf (header_name, sizeof (header_name), "X-Spam-%s", metric_res->metric->name);
 
-       if (!check_metric_settings (task, metric_res->metric, &ms, &rs)) {
+       if (!check_metric_settings (metric_res, &ms, &rs)) {
                ms = metric_res->metric->required_score;
        }
        if (metric_res->score >= ms) {
index dbc13defa27dca1c55a36fe0956f346576f43afa..cfcab7cb55e6883b88089e3ae4ca1754403f96c1 100644 (file)
@@ -10,6 +10,7 @@
 #include "symbols_cache.h"
 
 struct worker_task;
+struct rspamd_settings;
 
 typedef double (*metric_cons_func)(struct worker_task *task, const gchar *metric_name, const gchar *func_name);
 typedef void (*filter_func)(struct worker_task *task);
@@ -74,6 +75,8 @@ struct metric_result {
        GHashTable *symbols;                                                    /**< symbols of metric                                          */
        gboolean checked;                                                               /**< whether metric result is consolidated  */
        double grow_factor;                                                             /**< current grow factor                                        */
+       struct rspamd_settings *user_settings;                  /**< settings for metric                                        */
+       struct rspamd_settings *domain_settings;                /**< settings for metric                                        */
 };
 
 /**
index ff626bc8510fddf264438955f26b40dfcb893b56..3eae408de1e8fb3d29d09eada355f401f289ff11 100644 (file)
@@ -1088,7 +1088,7 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
                m = g_hash_table_lookup (task->cfg->metrics, DEFAULT_METRIC);
                default_required_score = m->required_score;
                default_score = 0;
-               if (!check_metric_settings (task, m, &ms, &rs)) {
+               if (!check_metric_settings (metric_res, &ms, &rs)) {
                        ms = m->required_score;
                        rs = m->reject_score;
                }
@@ -1119,11 +1119,11 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
                        default_score = metric_res->score;
                }
 
-               if (!check_metric_settings (task, metric_res->metric, &ms, &rs)) {
+               if (!check_metric_settings (metric_res, &ms, &rs)) {
                        ms = metric_res->metric->required_score;
                        rs = metric_res->metric->reject_score;
                }
-               if (!check_metric_action_settings (task, metric_res->metric,
+               if (!check_metric_action_settings (task, metric_res,
                                metric_res->score, &action)) {
                        action = check_metric_action (metric_res->score, ms,
                                        metric_res->metric);
index 1d0853f0a9292d5c6d22fe16b4147c8cacaf6fda..e0ca4805be2c8bb992af807cd22e41b71db495f2 100644 (file)
@@ -434,39 +434,38 @@ check_bwhitelist (struct worker_task *task, struct rspamd_settings *s, gboolean
 }
 
 gboolean
-check_metric_settings (struct worker_task * task, struct metric * metric, double *score, double *rscore)
+check_metric_settings (struct metric_result *res, double *score, double *rscore)
 {
-       struct rspamd_settings         *us = NULL, *ds = NULL;
+       struct rspamd_settings         *us = res->user_settings, *ds = res->domain_settings;
        double                         *sc, *rs;
+       struct metric                  *metric = res->metric;
 
        *rscore = DEFAULT_REJECT_SCORE;
 
-       if (check_setting (task, &us, &ds)) {
-               if (us != NULL) {
-                       if ((rs = g_hash_table_lookup (us->reject_scores, metric->name)) != NULL) {
-                               *rscore = *rs;
-                       }
-                       if ((sc = g_hash_table_lookup (us->metric_scores, metric->name)) != NULL) {
-                               *score = *sc;
-                               return TRUE;
-                       }
-                       /* Now check in domain settings */
-                       if (ds && ((rs = g_hash_table_lookup (ds->reject_scores, metric->name)) != NULL)) {
-                               *rscore = *rs;
-                       }
-                       if (ds && (sc = g_hash_table_lookup (ds->metric_scores, metric->name)) != NULL) {
-                               *score = *sc;
-                               return TRUE;
-                       }
+       if (us != NULL) {
+               if ((rs = g_hash_table_lookup (us->reject_scores, metric->name)) != NULL) {
+                       *rscore = *rs;
                }
-               else if (ds != NULL) {
-                       if ((rs = g_hash_table_lookup (ds->reject_scores, metric->name)) != NULL) {
-                               *rscore = *rs;
-                       }
-                       if ((sc = g_hash_table_lookup (ds->metric_scores, metric->name)) != NULL) {
-                               *score = *sc;
-                               return TRUE;
-                       }
+               if ((sc = g_hash_table_lookup (us->metric_scores, metric->name)) != NULL) {
+                       *score = *sc;
+                       return TRUE;
+               }
+               /* Now check in domain settings */
+               if (ds && ((rs = g_hash_table_lookup (ds->reject_scores, metric->name)) != NULL)) {
+                       *rscore = *rs;
+               }
+               if (ds && (sc = g_hash_table_lookup (ds->metric_scores, metric->name)) != NULL) {
+                       *score = *sc;
+                       return TRUE;
+               }
+       }
+       else if (ds != NULL) {
+               if ((rs = g_hash_table_lookup (ds->reject_scores, metric->name)) != NULL) {
+                       *rscore = *rs;
+               }
+               if ((sc = g_hash_table_lookup (ds->metric_scores, metric->name)) != NULL) {
+                       *score = *sc;
+                       return TRUE;
                }
        }
 
@@ -474,76 +473,66 @@ check_metric_settings (struct worker_task * task, struct metric * metric, double
 }
 
 gboolean
-check_metric_action_settings (struct worker_task *task, struct metric *metric, double score, enum rspamd_metric_action *result)
+check_metric_action_settings (struct worker_task *task, struct metric_result *res,
+               double score, enum rspamd_metric_action *result)
 {
-       struct rspamd_settings         *us = NULL, *ds = NULL;
+       struct rspamd_settings         *us = res->user_settings, *ds = res->domain_settings;
        struct metric_action           *act, *sel = NULL;
        GList                          *cur;
-       enum rspamd_metric_action       res = METRIC_ACTION_NOACTION;
+       enum rspamd_metric_action       r = METRIC_ACTION_NOACTION;
        gboolean                        black;
        double                          rej = 0.;
 
-       if (check_setting (task, &us, &ds)) {
-               if (us != NULL) {
-                       /* Check whitelist and set appropriate action for whitelisted users */
-                       if (check_bwhitelist(task, us, &black)) {
-                               if (black) {
-                                       *result = METRIC_ACTION_REJECT;
-                               }
-                               else {
-                                       *result = METRIC_ACTION_NOACTION;
-                               }
-                               return TRUE;
+       if (us != NULL) {
+               /* Check whitelist and set appropriate action for whitelisted users */
+               if (check_bwhitelist(task, us, &black)) {
+                       if (black) {
+                               *result = METRIC_ACTION_REJECT;
                        }
-                       if ((cur = g_hash_table_lookup (us->metric_actions, metric->name)) != NULL) {
-
-                               while (cur) {
-                                       act = cur->data;
-                                       if (score >= act->score) {
-                                               res = act->action;
-                                               sel = act;
-                                       }
-                                       if (res == METRIC_ACTION_REJECT) {
-                                               rej = act->score;
-                                       }
-                                       cur = g_list_next (cur);
-                               }
+                       else {
+                               *result = METRIC_ACTION_NOACTION;
                        }
+                       return TRUE;
                }
-               else if (ds != NULL) {
-                       /* Check whitelist and set appropriate action for whitelisted users */
-                       if (check_bwhitelist(task, ds, &black)) {
-                               if (black) {
-                                       *result = METRIC_ACTION_REJECT;
+               if ((cur = g_hash_table_lookup (us->metric_actions, res->metric->name)) != NULL) {
+                       while (cur) {
+                               act = cur->data;
+                               if (score >= act->score) {
+                                       r = act->action;
+                                       sel = act;
                                }
-                               else {
-                                       *result = METRIC_ACTION_NOACTION;
+                               if (r == METRIC_ACTION_REJECT) {
+                                       rej = act->score;
                                }
-                               return TRUE;
+                               cur = g_list_next (cur);
                        }
-                       if ((cur = g_hash_table_lookup (ds->metric_actions, metric->name)) != NULL) {
-                               while (cur) {
-                                       act = cur->data;
-                                       if (score >= act->score) {
-                                               res = act->action;
-                                               sel = act;
-                                       }
-                                       cur = g_list_next (cur);
+               }
+       }
+       else if (ds != NULL) {
+               /* Check whitelist and set appropriate action for whitelisted users */
+               if (check_bwhitelist(task, ds, &black)) {
+                       if (black) {
+                               *result = METRIC_ACTION_REJECT;
+                       }
+                       else {
+                               *result = METRIC_ACTION_NOACTION;
+                       }
+                       return TRUE;
+               }
+               if ((cur = g_hash_table_lookup (ds->metric_actions, res->metric->name)) != NULL) {
+                       while (cur) {
+                               act = cur->data;
+                               if (score >= act->score) {
+                                       r = act->action;
+                                       sel = act;
                                }
+                               cur = g_list_next (cur);
                        }
                }
        }
 
        if (sel != NULL && result != NULL) {
-               *result = res;
-               if (res != rej && rej != 0.) {
-                       msg_info ("<%s> applying action %s with score %.2f, reject: %.2f", task->message_id,
-                                       str_action_metric (sel->action), sel->score, rej);
-               }
-               else {
-                       msg_info ("<%s> applying action %s with score %.2f", task->message_id,
-                                                               str_action_metric (sel->action), sel->score);
-               }
+               *result = r;
                return TRUE;
        }
 
@@ -551,29 +540,48 @@ check_metric_action_settings (struct worker_task *task, struct metric *metric, d
 }
 
 gboolean
-check_factor_settings (struct worker_task * task, const gchar *symbol, double *factor)
+apply_metric_settings (struct worker_task *task, struct metric *metric, struct metric_result *res)
 {
        struct rspamd_settings         *us = NULL, *ds = NULL;
-       double                         *fc;
 
        if (check_setting (task, &us, &ds)) {
-               if (us != NULL) {
-                       /* First search in user's settings */
-                       if ((fc = g_hash_table_lookup (us->factors, symbol)) != NULL) {
-                               *factor = *fc;
-                               return TRUE;
+               if (us != NULL || ds != NULL) {
+                       if (us != NULL) {
+                               res->user_settings = us;
                        }
-                       /* Now check in domain settings */
-                       if (ds && (fc = g_hash_table_lookup (ds->factors, symbol)) != NULL) {
-                               *factor = *fc;
-                               return TRUE;
+                       if (ds != NULL) {
+                               res->domain_settings = ds;
                        }
                }
-               else if (ds != NULL) {
-                       if ((fc = g_hash_table_lookup (ds->factors, symbol)) != NULL) {
-                               *factor = *fc;
-                               return TRUE;
-                       }
+               else {
+                       return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
+gboolean
+check_factor_settings (struct metric_result *res, const gchar *symbol, double *factor)
+{
+       double                         *fc;
+
+       if (res->user_settings != NULL) {
+               /* First search in user's settings */
+               if ((fc = g_hash_table_lookup (res->user_settings->factors, symbol)) != NULL) {
+                       *factor = *fc;
+                       return TRUE;
+               }
+               /* Now check in domain settings */
+               if (res->domain_settings && (fc = g_hash_table_lookup (res->domain_settings->factors, symbol)) != NULL) {
+                       *factor = *fc;
+                       return TRUE;
+               }
+       }
+       else if (res->domain_settings != NULL) {
+               if ((fc = g_hash_table_lookup (res->domain_settings->factors, symbol)) != NULL) {
+                       *factor = *fc;
+                       return TRUE;
                }
        }
 
@@ -583,7 +591,7 @@ check_factor_settings (struct worker_task * task, const gchar *symbol, double *f
 
 
 gboolean
-check_want_spam (struct worker_task * task)
+check_want_spam (struct worker_task *task)
 {
        struct rspamd_settings         *us = NULL, *ds = NULL;
 
index 6ac96cf7a2bf6f8ad627f197e51e70e97904059d..c0fccbf1691ac456c140ec6a7867a7120773bbb5 100644 (file)
@@ -18,9 +18,11 @@ struct rspamd_settings {
 
 gboolean read_settings (const gchar *path, struct config_file *cfg, GHashTable *table);
 void init_settings (struct config_file *cfg);
-gboolean check_metric_settings (struct worker_task *task, struct metric *metric, double *score, double *rscore);
-gboolean check_metric_action_settings (struct worker_task *task, struct metric *metric, double score, enum rspamd_metric_action *result);
-gboolean check_factor_settings (struct worker_task *task, const gchar *symbol, double *factor);
+gboolean check_metric_settings (struct metric_result *res, double *score, double *rscore);
+gboolean check_metric_action_settings (struct worker_task *task, struct metric_result *res, double score, enum rspamd_metric_action *result);
+gboolean check_factor_settings (struct metric_result *res, const gchar *symbol, double *factor);
 gboolean check_want_spam (struct worker_task *task);
 
+gboolean apply_metric_settings (struct worker_task *task, struct metric *metric, struct metric_result *res);
+
 #endif
index 5aa5b5e41e10d830d4e659e67f4329e1cba39671..27dffd275f115ac3927e4cda78c0d94d221604b1 100644 (file)
@@ -152,11 +152,11 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
 
        task = cd->session->task;
 
-       if (!check_metric_settings (task, metric_res->metric, &ms, &rs)) {
+       if (!check_metric_settings (metric_res, &ms, &rs)) {
                ms = metric_res->metric->required_score;
                rs = metric_res->metric->reject_score;
        }
-       if (! check_metric_action_settings (task, metric_res->metric, metric_res->score, &action)) {
+       if (! check_metric_action_settings (task, metric_res, metric_res->score, &action)) {
                action = check_metric_action (metric_res->score, ms, metric_res->metric);
        }
        if (metric_res->score >= ms) {