From 9e6acadd7ce323f42ebed02237d064305df32249 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 30 Jun 2011 18:32:11 +0400 Subject: [PATCH] * Improve performance of settings lookup --- src/filter.c | 7 +- src/filter.h | 3 + src/protocol.c | 6 +- src/settings.c | 200 ++++++++++++++++++++++++----------------------- src/settings.h | 8 +- src/smtp_utils.c | 4 +- 6 files changed, 122 insertions(+), 106 deletions(-) diff --git a/src/filter.c b/src/filter.c index b625e4c72..b48bf64ba 100644 --- a/src/filter.c +++ b/src/filter.c @@ -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) { diff --git a/src/filter.h b/src/filter.h index dbc13defa..cfcab7cb5 100644 --- a/src/filter.h +++ b/src/filter.h @@ -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 */ }; /** diff --git a/src/protocol.c b/src/protocol.c index ff626bc85..3eae408de 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -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); diff --git a/src/settings.c b/src/settings.c index 1d0853f0a..e0ca4805b 100644 --- a/src/settings.c +++ b/src/settings.c @@ -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; diff --git a/src/settings.h b/src/settings.h index 6ac96cf7a..c0fccbf16 100644 --- a/src/settings.h +++ b/src/settings.h @@ -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 diff --git a/src/smtp_utils.c b/src/smtp_utils.c index 5aa5b5e41..27dffd275 100644 --- a/src/smtp_utils.c +++ b/src/smtp_utils.c @@ -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) { -- 2.39.5