|
|
@@ -36,8 +36,7 @@ struct rspamd_re_class { |
|
|
|
enum rspamd_re_type type; |
|
|
|
gpointer type_data; |
|
|
|
gsize type_len; |
|
|
|
GHashTable *re_ids; |
|
|
|
GPtrArray *all_re; |
|
|
|
GHashTable *re; |
|
|
|
gchar hash[rspamd_cryptobox_HASHBYTES * 2 + 1]; |
|
|
|
}; |
|
|
|
|
|
|
@@ -77,7 +76,6 @@ rspamd_re_cache_destroy (struct rspamd_re_cache *cache) |
|
|
|
GHashTableIter it; |
|
|
|
gpointer k, v; |
|
|
|
struct rspamd_re_class *re_class; |
|
|
|
rspamd_regexp_t *re; |
|
|
|
guint i; |
|
|
|
|
|
|
|
g_assert (cache != NULL); |
|
|
@@ -86,14 +84,7 @@ rspamd_re_cache_destroy (struct rspamd_re_cache *cache) |
|
|
|
while (g_hash_table_iter_next (&it, &k, &v)) { |
|
|
|
re_class = v; |
|
|
|
g_hash_table_iter_steal (&it); |
|
|
|
|
|
|
|
for (i = 0; i < re_class->all_re->len; i++) { |
|
|
|
re = g_ptr_array_index (re_class->all_re, i); |
|
|
|
|
|
|
|
rspamd_regexp_set_cache_id (re, RSPAMD_INVALID_ID); |
|
|
|
rspamd_regexp_unref (re); |
|
|
|
} |
|
|
|
|
|
|
|
g_hash_table_unref (re_class->re); |
|
|
|
g_slice_free1 (sizeof (*re_class), re_class); |
|
|
|
} |
|
|
|
|
|
|
@@ -120,6 +111,7 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re, |
|
|
|
{ |
|
|
|
guint64 class_id; |
|
|
|
struct rspamd_re_class *re_class; |
|
|
|
rspamd_regexp_t *nre; |
|
|
|
|
|
|
|
g_assert (cache != NULL); |
|
|
|
g_assert (re != NULL); |
|
|
@@ -132,29 +124,60 @@ rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re, |
|
|
|
re_class->id = class_id; |
|
|
|
re_class->type_len = datalen; |
|
|
|
re_class->type = type; |
|
|
|
re_class->re_ids = g_hash_table_new (rspamd_regexp_hash, |
|
|
|
rspamd_regexp_equal); |
|
|
|
re_class->re = g_hash_table_new_full (rspamd_regexp_hash, |
|
|
|
rspamd_regexp_equal, NULL, (GDestroyNotify)rspamd_regexp_unref); |
|
|
|
|
|
|
|
if (datalen > 0) { |
|
|
|
re_class->type_data = g_slice_alloc (datalen); |
|
|
|
memcpy (re_class->type_data, type_data, datalen); |
|
|
|
} |
|
|
|
|
|
|
|
re_class->all_re = g_ptr_array_new (); |
|
|
|
g_hash_table_insert (cache->re_classes, &re_class->id, re_class); |
|
|
|
} |
|
|
|
|
|
|
|
g_ptr_array_add (re_class->all_re, rspamd_regexp_ref (re)); |
|
|
|
/* |
|
|
|
* We set re id based on the global position in the cache |
|
|
|
*/ |
|
|
|
rspamd_regexp_set_cache_id (re, cache->nre ++); |
|
|
|
nre = rspamd_regexp_ref (re); |
|
|
|
g_hash_table_insert (re_class->re, re, re); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
rspamd_re_cache_replace (struct rspamd_re_cache *cache, |
|
|
|
rspamd_regexp_t *what, |
|
|
|
enum rspamd_re_type type, |
|
|
|
gpointer type_data, |
|
|
|
gsize datalen, |
|
|
|
rspamd_regexp_t *with) |
|
|
|
{ |
|
|
|
guint64 class_id, re_id; |
|
|
|
struct rspamd_re_class *re_class; |
|
|
|
rspamd_regexp_t *src; |
|
|
|
|
|
|
|
g_assert (cache != NULL); |
|
|
|
g_assert (what != NULL); |
|
|
|
g_assert (with != NULL); |
|
|
|
|
|
|
|
class_id = rspamd_re_cache_class_id (type, type_data, datalen); |
|
|
|
re_class = g_hash_table_lookup (cache->re_classes, &class_id); |
|
|
|
|
|
|
|
if (re_class != NULL) { |
|
|
|
re_id = rspamd_regexp_get_cache_id (what); |
|
|
|
|
|
|
|
g_assert (re_id != RSPAMD_INVALID_ID); |
|
|
|
src = g_hash_table_lookup (re_class->re, what); |
|
|
|
|
|
|
|
if (src) { |
|
|
|
g_hash_table_replace (re_class->re, what, with); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|
rspamd_re_cache_init (struct rspamd_re_cache *cache) |
|
|
|
{ |
|
|
|
GHashTableIter it; |
|
|
|
GHashTableIter it, cit; |
|
|
|
gpointer k, v; |
|
|
|
struct rspamd_re_class *re_class; |
|
|
|
rspamd_cryptobox_hash_state_t st; |
|
|
@@ -171,9 +194,10 @@ rspamd_re_cache_init (struct rspamd_re_cache *cache) |
|
|
|
rspamd_cryptobox_hash_init (&st, NULL, 0); |
|
|
|
rspamd_cryptobox_hash_update (&st, (gpointer)&re_class->id, |
|
|
|
sizeof (re_class->id)); |
|
|
|
g_hash_table_iter_init (&cit, re_class->re); |
|
|
|
|
|
|
|
for (i = 0; i < re_class->all_re->len; i ++) { |
|
|
|
re = g_ptr_array_index (re_class->all_re, i); |
|
|
|
while (g_hash_table_iter_next (&cit, &k, &v)) { |
|
|
|
re = v; |
|
|
|
rspamd_cryptobox_hash_update (&st, rspamd_regexp_get_id (re), |
|
|
|
rspamd_cryptobox_HASHBYTES); |
|
|
|
} |