diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2014-04-21 16:25:51 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2014-04-21 16:25:51 +0100 |
commit | 61555065f3d1c8badcc9573691232f1b6e42988c (patch) | |
tree | 563d5b7cb8c468530f7e79c4da0a75267b1184e1 /src/libutil/bloom.c | |
parent | ad5bf825b7f33bc10311673991f0cc888e69c0b1 (diff) | |
download | rspamd-61555065f3d1c8badcc9573691232f1b6e42988c.tar.gz rspamd-61555065f3d1c8badcc9573691232f1b6e42988c.zip |
Rework project structure, remove trash files.
Diffstat (limited to 'src/libutil/bloom.c')
-rw-r--r-- | src/libutil/bloom.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/src/libutil/bloom.c b/src/libutil/bloom.c new file mode 100644 index 000000000..f857d2e49 --- /dev/null +++ b/src/libutil/bloom.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009-2012, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "bloom.h" +#include "xxhash.h" + +/* 4 bits are used for counting (implementing delete operation) */ +#define SIZE_BIT 4 + +/* These macroes are for 4 bits for counting element */ +#define INCBIT(a, n, acc) do { \ + acc = a[n * SIZE_BIT / CHAR_BIT] & (0xF << (n % (CHAR_BIT / SIZE_BIT) * SIZE_BIT)); \ + acc ++; \ + acc &= 0xF; \ + \ + a[n * SIZE_BIT / CHAR_BIT] &= (0xF << (4 - (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT))); \ + a[n * SIZE_BIT / CHAR_BIT] |= (acc << (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT)); \ +} while (0); + +#define DECBIT(a, n, acc) do { \ + acc = a[n * SIZE_BIT / CHAR_BIT] & (0xF << (n % (CHAR_BIT / SIZE_BIT) * SIZE_BIT)); \ + acc --; \ + acc &= 0xF; \ + \ + a[n * SIZE_BIT / CHAR_BIT] &= (0xF << (4 - (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT))); \ + a[n * SIZE_BIT / CHAR_BIT] |= (acc << (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT)); \ +} while (0); + +#define GETBIT(a, n) (a[n * SIZE_BIT / CHAR_BIT] & (0xF << (n % (CHAR_BIT/SIZE_BIT) * SIZE_BIT))) + +/* Common hash functions */ + + +rspamd_bloom_filter_t * +rspamd_bloom_create (size_t size, size_t nfuncs, ...) +{ + rspamd_bloom_filter_t *bloom; + va_list l; + gsize n; + + if (!(bloom = g_malloc (sizeof (rspamd_bloom_filter_t)))) { + return NULL; + } + if (!(bloom->a = g_new0 (gchar, (size + CHAR_BIT - 1) / CHAR_BIT * SIZE_BIT))) { + g_free (bloom); + return NULL; + } + if (!(bloom->seeds = g_new0 (guint32, nfuncs))) { + g_free (bloom->a); + g_free (bloom); + return NULL; + } + + va_start (l, nfuncs); + for (n = 0; n < nfuncs; ++n) { + bloom->seeds[n] = va_arg (l, guint32); + } + va_end (l); + + bloom->nfuncs = nfuncs; + bloom->asize = size; + + return bloom; +} + +void +rspamd_bloom_destroy (rspamd_bloom_filter_t * bloom) +{ + g_free (bloom->a); + g_free (bloom->seeds); + g_free (bloom); +} + +gboolean +rspamd_bloom_add (rspamd_bloom_filter_t * bloom, const gchar *s) +{ + size_t n, len; + u_char t; + guint v; + + if (s == NULL) { + return FALSE; + } + len = strlen (s); + for (n = 0; n < bloom->nfuncs; ++n) { + v = XXH32 (s, len, bloom->seeds[n]) % bloom->asize; + INCBIT (bloom->a, v, t); + } + + return TRUE; +} + +gboolean +rspamd_bloom_del (rspamd_bloom_filter_t * bloom, const gchar *s) +{ + size_t n, len; + u_char t; + guint v; + + if (s == NULL) { + return FALSE; + } + len = strlen (s); + for (n = 0; n < bloom->nfuncs; ++n) { + v = XXH32 (s, len, bloom->seeds[n]) % bloom->asize; + DECBIT (bloom->a, v, t); + } + + return TRUE; + +} + +gboolean +rspamd_bloom_check (rspamd_bloom_filter_t * bloom, const gchar *s) +{ + size_t n, len; + guint v; + + if (s == NULL) { + return FALSE; + } + len = strlen (s); + for (n = 0; n < bloom->nfuncs; ++n) { + v = XXH32 (s, len, bloom->seeds[n]) % bloom->asize; + if (!(GETBIT (bloom->a, v))) { + return FALSE; + } + } + + return TRUE; +} |