From 3440686c5933b28e255e3e44ddcc6b8bcdda658f Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 22 Dec 2016 18:03:32 +0000 Subject: [PATCH] [Feature] Use t1ha for hashes, allow inlining --- src/libutil/str_util.c | 47 ++++++++++++++++++++++++++++-------------- src/libutil/str_util.h | 1 + 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index 37250c6fc..7b65f53a7 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -18,6 +18,7 @@ #include "cryptobox.h" #include "url.h" #include "str_util.h" +#include "contrib/t1ha/t1ha.h" #include const guchar lc_map[256] = { @@ -183,45 +184,59 @@ rspamd_strcase_equal (gconstpointer v, gconstpointer v2) return FALSE; } -static guint -rspamd_icase_hash (const gchar *in, gsize len) +guint64 +rspamd_icase_hash (const gchar *in, gsize len, guint64 seed) { - guint leftover = len % 4; + guint leftover = len % sizeof (guint64); guint fp, i; const uint8_t* s = (const uint8_t*) in; union { struct { - guchar c1, c2, c3, c4; + guchar c1, c2, c3, c4, c5, c6, c7, c8; } c; - guint32 pp; + guint64 pp; } u; - rspamd_cryptobox_fast_hash_state_t st; + guint64 h = seed; fp = len - leftover; - rspamd_cryptobox_fast_hash_init (&st, rspamd_hash_seed ()); - for (i = 0; i != fp; i += 4) { + for (i = 0; i != fp; i += 8) { u.c.c1 = s[i], u.c.c2 = s[i + 1], u.c.c3 = s[i + 2], u.c.c4 = s[i + 3]; + u.c.c5 = s[i + 4], u.c.c6 = s[i + 5], u.c.c7 = s[i + 6], u.c.c8 = s[i + 7]; u.c.c1 = lc_map[u.c.c1]; u.c.c2 = lc_map[u.c.c2]; u.c.c3 = lc_map[u.c.c3]; u.c.c4 = lc_map[u.c.c4]; - rspamd_cryptobox_fast_hash_update (&st, &u.pp, sizeof (u)); + u.c.c5 = lc_map[u.c.c5]; + u.c.c6 = lc_map[u.c.c6]; + u.c.c7 = lc_map[u.c.c7]; + u.c.c8 = lc_map[u.c.c8]; + h = t1ha (&u.pp, sizeof (u), h); } u.pp = 0; + switch (leftover) { + case 7: + u.c.c7 = lc_map[(guchar)s[i++]]; /* fallthrough */ + case 6: + u.c.c6 = lc_map[(guchar)s[i++]]; /* fallthrough */ + case 5: + u.c.c5 = lc_map[(guchar)s[i++]]; /* fallthrough */ + case 4: + u.c.c4 = lc_map[(guchar)s[i++]]; /* fallthrough */ case 3: - u.c.c3 = lc_map[(guchar)s[i++]]; + u.c.c3 = lc_map[(guchar)s[i++]]; /* fallthrough */ case 2: - u.c.c2 = lc_map[(guchar)s[i++]]; + u.c.c2 = lc_map[(guchar)s[i++]]; /* fallthrough */ case 1: u.c.c1 = lc_map[(guchar)s[i]]; - rspamd_cryptobox_fast_hash_update (&st, &u.pp, leftover); break; } - return rspamd_cryptobox_fast_hash_final (&st); + h = t1ha (&u.pp, sizeof (u), h); + + return h; } guint @@ -232,7 +247,7 @@ rspamd_strcase_hash (gconstpointer key) len = strlen (p); - return rspamd_icase_hash (p, len); + return rspamd_icase_hash (p, len, rspamd_hash_seed ()); } guint @@ -270,7 +285,7 @@ rspamd_ftok_icase_hash (gconstpointer key) { const rspamd_ftok_t *f = key; - return rspamd_icase_hash (f->begin, f->len); + return rspamd_icase_hash (f->begin, f->len, rspamd_hash_seed ()); } gboolean @@ -291,7 +306,7 @@ rspamd_gstring_icase_hash (gconstpointer key) { const GString *f = key; - return rspamd_icase_hash (f->str, f->len); + return rspamd_icase_hash (f->str, f->len, rspamd_hash_seed ()); } /* https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord */ diff --git a/src/libutil/str_util.h b/src/libutil/str_util.h index 094a6498c..941d141b4 100644 --- a/src/libutil/str_util.h +++ b/src/libutil/str_util.h @@ -45,6 +45,7 @@ void rspamd_str_lc_utf8 (gchar *str, guint size); /* * Hash table utility functions for case insensitive hashing */ +guint64 rspamd_icase_hash (const gchar *in, gsize len, guint64 seed); guint rspamd_strcase_hash (gconstpointer key); gboolean rspamd_strcase_equal (gconstpointer v, gconstpointer v2); -- 2.39.5