]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Fix] Use Fibonacci hashing for task pointer hash 5803/head
authorVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 22 Dec 2025 11:53:37 +0000 (11:53 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Mon, 22 Dec 2025 11:53:37 +0000 (11:53 +0000)
Use golden ratio multiplication for 64-bit to 32-bit pointer hashing.
This provides good distribution with minimal operations (1 multiply +
1 shift) and works well with kh_int_hash_func which is identity.

src/libserver/task.c

index 4c4341eb5743d692152ba323fb91a76110c32e8b..3ed0ee4e71dfaf496c1f2c3704277c73d79f8667 100644 (file)
@@ -51,28 +51,25 @@ __KHASH_IMPL(rspamd_req_headers_hash, static inline,
                         rspamd_ftok_t *, struct rspamd_request_header_chain *, 1,
                         rspamd_ftok_icase_hash, rspamd_ftok_icase_equal)
 
+/* Task pointer set for validating Lua task references */
+KHASH_SET_INIT_INT(rspamd_task_set);
+
+static khash_t(rspamd_task_set) *task_registry = NULL;
+
+#define TASK_REGISTRY_INITIAL_SIZE 16
+
 /*
- * Task pointer set for validating Lua task references.
- * Mix pointer bits to improve hash distribution since pointers
- * are typically aligned and have predictable low bits.
+ * Mix 64-bit pointer to 32-bit hash using Fibonacci hashing.
+ * Multiply by golden ratio and take high bits for good distribution.
+ * kh_int_hash_func is identity, so we do all mixing here.
  */
-static inline uint64_t
+static inline khint32_t
 rspamd_task_hash_ptr(struct rspamd_task *task)
 {
        uint64_t p = (uint64_t) (uintptr_t) task;
-       /* Mix bits: multiply by golden ratio prime and xor with shifted value */
-       p ^= p >> 33;
-       p *= 0xff51afd7ed558ccdULL;
-       p ^= p >> 33;
-       return p;
+       return (khint32_t) ((p * 11400714819323198485ULL) >> 32);
 }
 
-KHASH_SET_INIT_INT64(rspamd_task_set);
-
-static khash_t(rspamd_task_set) *task_registry = NULL;
-
-#define TASK_REGISTRY_INITIAL_SIZE 16
-
 void rspamd_task_registry_init(void)
 {
        if (task_registry == NULL) {