final_score = (*sdef->weight_ptr) * weight;
PTR_ARRAY_FOREACH (sdef->groups, i, gr) {
- k = kh_get (rspamd_symbols_group_hash,
- metric_res->sym_groups, GPOINTER_TO_INT (gr));
+ k = kh_get (rspamd_symbols_group_hash, metric_res->sym_groups, gr);
if (k == kh_end (metric_res->sym_groups)) {
k = kh_put (rspamd_symbols_group_hash, metric_res->sym_groups,
- GPOINTER_TO_INT (gr), &ret);
+ gr, &ret);
kh_value (metric_res->sym_groups, k) = 0;
}
- else {
- gr_score = &kh_value (metric_res->sym_groups, k);
- }
}
}
next_gf = task->cfg->grow_factor;
}
- diff = rspamd_check_group_score (task, symbol, gr, gr_score, diff);
+ if (sdef) {
+ PTR_ARRAY_FOREACH (sdef->groups, i, gr) {
+ gdouble cur_diff;
+
+ k = kh_get (rspamd_symbols_group_hash,
+ metric_res->sym_groups, gr);
+ g_assert (k != kh_end (metric_res->sym_groups));
+ gr_score = &kh_value (metric_res->sym_groups, k);
+ cur_diff = rspamd_check_group_score (task, symbol, gr,
+ gr_score, diff);
+
+ if (isnan (cur_diff)) {
+ /* Limit reached, do not add result */
+ diff = NAN;
+ break;
+ } else if (gr_score) {
+ *gr_score += cur_diff;
+
+ if (cur_diff < diff) {
+ /* Reduce */
+ diff = cur_diff;
+ }
+ }
+ }
+ }
if (!isnan (diff)) {
metric_res->score += diff;
metric_res->grow_factor = next_gf;
- if (gr_score) {
- *gr_score += diff;
- }
-
if (single) {
s->score = final_score;
- }
- else {
+ } else {
s->score += diff;
}
}
s->sym = sdef;
s->nshots = 1;
- final_score = rspamd_check_group_score (task, symbol, gr, gr_score, final_score);
+ if (sdef) {
+ /* Check group limits */
+ PTR_ARRAY_FOREACH (sdef->groups, i, gr) {
+ gdouble cur_score;
+
+ k = kh_get (rspamd_symbols_group_hash, metric_res->sym_groups, gr);
+ g_assert (k != kh_end (metric_res->sym_groups));
+ gr_score = &kh_value (metric_res->sym_groups, k);
+ cur_score = rspamd_check_group_score (task, symbol, gr,
+ gr_score, final_score);
+
+ if (isnan (cur_score)) {
+ /* Limit reached, do not add result */
+ final_score = NAN;
+ break;
+ } else if (gr_score) {
+ *gr_score += cur_score;
+
+ if (cur_score < final_score) {
+ /* Reduce */
+ final_score = cur_score;
+ }
+ }
+ }
+ }
if (!isnan (final_score)) {
metric_res->score += final_score;
metric_res->grow_factor = next_gf;
s->score = final_score;
-
- if (gr_score) {
- *gr_score += final_score;
- }
-
}
else {
s->score = 0;
/**
* Rspamd symbol
*/
-KHASH_MAP_INIT_STR (rspamd_options_hash, struct rspamd_symbol_option *);
+KHASH_MAP_INIT_STR (rspamd_options_hash, struct rspamd_symbol_option *);
struct rspamd_symbol_result {
double score; /**< symbol's score */
khash_t(rspamd_options_hash) *options; /**< list of symbol's options */
* Result of metric processing
*/
KHASH_MAP_INIT_STR (rspamd_symbols_hash, struct rspamd_symbol_result);
-KHASH_MAP_INIT_INT (rspamd_symbols_group_hash, double);
-
+#if UINTPTR_MAX <= UINT_MAX
+/* 32 bit */
+#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>1)
+#else
+/* likely 64 bit */
+#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>3)
+#endif
+#define rspamd_ptr_equal_func(a, b) ((a) == (b))
+KHASH_INIT (rspamd_symbols_group_hash,
+ void *,
+ double,
+ 1,
+ rspamd_ptr_hash_func,
+ rspamd_ptr_equal_func);
struct rspamd_metric_result {
double score; /**< total score */
double grow_factor; /**< current grow factor */