aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil/util.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-04-14 16:16:52 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-04-14 16:16:52 +0100
commitea53cb781388f3d07ac29170267678003633a17b (patch)
tree02870498d6cc403fa2d98320268976fa80856b82 /src/libutil/util.c
parente3771cc9752fb1f20bd389984d868e7af1208ce4 (diff)
downloadrspamd-ea53cb781388f3d07ac29170267678003633a17b.tar.gz
rspamd-ea53cb781388f3d07ac29170267678003633a17b.zip
Improve rspamd internal hash functions.
Diffstat (limited to 'src/libutil/util.c')
-rw-r--r--src/libutil/util.c87
1 files changed, 45 insertions, 42 deletions
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 383842a07..506d5b0e0 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -1258,31 +1258,54 @@ rspamd_strcase_equal (gconstpointer v, gconstpointer v2)
return FALSE;
}
+static guint
+rspamd_icase_hash (const gchar *in, gsize len)
+{
+ guint leftover = len % 8;
+ guint fp, i;
+ const uint8_t* s = (const uint8_t*) in;
+ union {
+ guchar c1, c2, c3, c4;
+ guint32 pp;
+ } u;
+ XXH64_state_t st;
+
+ fp = len - leftover;
+ XXH64_reset (&st, 0xdeadbabe);
+
+ for (i = 0; i != fp; i += 4) {
+ u.c1 = s[i], u.c2 = s[i + 1], u.c3 = s[i + 2], u.c4 = s[i + 3];
+ u.c1 = lc_map[u.c1];
+ u.c2 = lc_map[u.c2];
+ u.c3 = lc_map[u.c3];
+ u.c4 = lc_map[u.c4];
+ XXH64_update (&st, &u.pp, sizeof (u));
+ }
+
+ u.pp = 0;
+ switch (leftover) {
+ case 3:
+ u.c3 = lc_map[(guchar)s[i++]];
+ case 2:
+ u.c2 = lc_map[(guchar)s[i++]];
+ case 1:
+ u.c1 = lc_map[(guchar)s[i]];
+ XXH64_update (&st, &u.pp, sizeof (u));
+ break;
+ }
+
+ return XXH64_digest (&st);
+}
guint
rspamd_strcase_hash (gconstpointer key)
{
const gchar *p = key;
- gchar buf[256];
- guint i = 0;
- gpointer xxh;
-
- xxh = XXH32_init (0);
- while (*p != '\0') {
- buf[i] = g_ascii_tolower (*p);
- i++;
- p++;
- if (i == sizeof (buf)) {
- XXH32_update (xxh, buf, i);
- i = 0;
- }
- }
+ gsize len;
- if (i > 0) {
- XXH32_update (xxh, buf, i);
- }
+ len = strlen (p);
- return XXH32_digest (xxh);
+ return rspamd_icase_hash (p, len);
}
guint
@@ -1292,7 +1315,7 @@ rspamd_str_hash (gconstpointer key)
len = strlen ((const gchar *)key);
- return XXH32 (key, len, 0);
+ return XXH64 (key, len, 0xdeadbabe);
}
gboolean
@@ -1302,7 +1325,7 @@ rspamd_str_equal (gconstpointer v, gconstpointer v2)
}
gboolean
-rspamd_fstring_equal (gconstpointer v, gconstpointer v2)
+rspamd_fstring_icase_equal (gconstpointer v, gconstpointer v2)
{
const rspamd_fstring_t *f1 = v, *f2 = v2;
if (f1->len == f2->len &&
@@ -1315,31 +1338,11 @@ rspamd_fstring_equal (gconstpointer v, gconstpointer v2)
guint
-rspamd_fstring_hash (gconstpointer key)
+rspamd_fstring_icase_hash (gconstpointer key)
{
const rspamd_fstring_t *f = key;
- const gchar *p;
- guint i = 0;
- gchar buf[256];
- gpointer xxh;
-
- xxh = XXH32_init (0);
- p = f->begin;
- while (p - f->begin < (gint)f->len) {
- buf[i] = g_ascii_tolower (*p);
- i++;
- p++;
- if (i == sizeof (buf)) {
- XXH32_update (xxh, buf, i);
- i = 0;
- }
- }
-
- if (i > 0) {
- XXH32_update (xxh, buf, i);
- }
- return XXH32_digest (xxh);
+ return rspamd_icase_hash (f->begin, f->len);
}
void