aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-06-30 18:32:11 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-06-30 18:32:11 +0400
commit9e6acadd7ce323f42ebed02237d064305df32249 (patch)
tree11ecda90995e02204d5f14c1fcabee893bdceab3
parentb3c36d4946f675619b81c9223f5ac1a86c55c55c (diff)
downloadrspamd-9e6acadd7ce323f42ebed02237d064305df32249.tar.gz
rspamd-9e6acadd7ce323f42ebed02237d064305df32249.zip
* Improve performance of settings lookup
-rw-r--r--src/filter.c7
-rw-r--r--src/filter.h3
-rw-r--r--src/protocol.c6
-rw-r--r--src/settings.c200
-rw-r--r--src/settings.h8
-rw-r--r--src/smtp_utils.c4
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) {