Browse Source

Add replacement method for expressions in the confi

tags/1.1.0
Vsevolod Stakhov 8 years ago
parent
commit
0943c1627c
2 changed files with 58 additions and 18 deletions
  1. 42
    18
      src/libserver/re_cache.c
  2. 16
    0
      src/libserver/re_cache.h

+ 42
- 18
src/libserver/re_cache.c View File

@@ -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);
}

+ 16
- 0
src/libserver/re_cache.h View File

@@ -55,6 +55,22 @@ struct rspamd_re_cache *rspamd_re_cache_new (void);
void rspamd_re_cache_add (struct rspamd_re_cache *cache, rspamd_regexp_t *re,
enum rspamd_re_type type, gpointer type_data, gsize datalen);

/**
* Replace regexp in the cache with another regexp
* @param cache cache object
* @param what re to replace
* @param type type of object
* @param type_data associated data with the type (e.g. header name)
* @param datalen associated data length
* @param with regexp object to replace the origin
*/
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);

/**
* Initialize and optimize re cache structure
*/

Loading…
Cancel
Save