return metric_res;
}
+static inline gdouble
+rspamd_check_group_score (struct rspamd_task *task,
+ const gchar *symbol,
+ struct rspamd_symbols_group *gr,
+ gdouble *group_score,
+ gdouble w)
+{
+ if (gr != NULL && group_score && gr->max_score > 0.0) {
+ if (*group_score >= gr->max_score && w > 0) {
+ msg_info_task ("maximum group score %.2f for group %s has been reached,"
+ " ignoring symbol %s with weight %.2f", gr->max_score,
+ gr->name, symbol, w);
+ return NAN;
+ }
+ else if (*group_score + w > gr->max_score) {
+ w = gr->max_score - *group_score;
+ }
+ }
+
+ return w;
+}
+
static struct rspamd_symbol_result *
insert_metric_result (struct rspamd_task *task,
struct rspamd_metric *metric,
{
struct rspamd_metric_result *metric_res;
struct rspamd_symbol_result *s = NULL;
- gdouble w, *gr_score = NULL;
+ gdouble w, *gr_score = NULL, next_gf = 1.0, diff;
struct rspamd_symbol *sdef;
struct rspamd_symbols_group *gr = NULL;
const ucl_object_t *mobj, *sobj;
}
}
- /* XXX: does not take grow factor into account */
- if (gr != NULL && gr_score != NULL && gr->max_score > 0.0) {
- if (*gr_score >= gr->max_score) {
- msg_info_task ("maximum group score %.2f for group %s has been reached,"
- " ignoring symbol %s with weight %.2f", gr->max_score,
- gr->name, symbol, w);
- return g_hash_table_lookup (metric_res->symbols, symbol);
- }
- else if (*gr_score + w > gr->max_score) {
- w = gr->max_score - *gr_score;
- }
-
- *gr_score += w;
- }
-
/* Add metric score */
if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) {
if (sdef && (sdef->flags & RSPAMD_SYMBOL_FLAG_ONESHOT)) {
if (rspamd_task_add_result_option (task, s, opt)) {
if (!single) {
- /* Handle grow factor */
- if (metric_res->grow_factor && w > 0) {
- w *= metric_res->grow_factor;
- metric_res->grow_factor *= metric->grow_factor;
- }
- s->score += w;
- metric_res->score += w;
+ diff = w;
}
else {
if (fabs (s->score) < fabs (w)) {
/* Replace less weight with a bigger one */
- metric_res->score = metric_res->score - s->score + w;
- s->score = w;
+ diff = metric_res->score - s->score + w;
+ }
+ else {
+ diff = 0;
+ }
+ }
+
+ if (diff) {
+ /* Handle grow factor */
+ if (metric_res->grow_factor && diff > 0) {
+ diff *= metric_res->grow_factor;
+ next_gf *= metric->grow_factor;
+ }
+ else if (diff > 0) {
+ next_gf = metric->grow_factor;
+ }
+
+ diff = rspamd_check_group_score (task, symbol, gr, gr_score, diff);
+
+ if (!isnan (w)) {
+ metric_res->score += diff;
+ metric_res->grow_factor = next_gf;
+
+ if (gr_score) {
+ *gr_score += diff;
+ }
+
+ if (single) {
+ s->score = w;
+ }
+ else {
+ s->score += diff;
+ }
}
}
}
/* Handle grow factor */
if (metric_res->grow_factor && w > 0) {
w *= metric_res->grow_factor;
- metric_res->grow_factor *= metric->grow_factor;
+ next_gf *= metric->grow_factor;
}
else if (w > 0) {
- metric_res->grow_factor = metric->grow_factor;
+ next_gf = metric->grow_factor;
}
- s->score = w;
s->name = symbol;
s->sym = sdef;
- metric_res->score += w;
+
+ w = rspamd_check_group_score (task, symbol, gr, gr_score, w);
+
+ if (!isnan (w)) {
+ metric_res->score += w;
+ metric_res->grow_factor = next_gf;
+ s->score = w;
+
+ if (gr_score) {
+ *gr_score += w;
+ }
+
+ }
+ else {
+ s->score = 0;
+ }
rspamd_task_add_result_option (task, s, opt);
g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s);