From 8f22da90187f7ebfe00d6af72e6c8cc7cf740ae8 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Wed, 14 Oct 2026 18:46:56 +0200 Subject: [PATCH] Use mulhash for integer keys while retaining inthash_u64 on 32-bit architectures --- cmdline/elem.c | 2 +- cmdline/elem.h | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/cmdline/elem.c b/cmdline/elem.c index db02a55c..c349a002 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -1773,7 +1773,7 @@ void bucket_free(void* void_bucket) void bucket_insert(tommy_hashdyn* bucket_hash, time_t time_at, block_off_t count, int justsynced) { - tommy_hash_t hash = tommy_inthash_u64(time_at); + tommy_hash_t hash = bucket_time_hash(time_at); tommy_node* i = tommy_hashdyn_bucket(bucket_hash, hash); while (i) { struct snapraid_bucket* entry = i->data; diff --git a/cmdline/elem.h b/cmdline/elem.h index 85edbf05..7e1ef4a0 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -984,7 +984,12 @@ int file_path_compare(const void* void_a, const void* void_b); */ static inline tommy_hash_t file_inode_hash(uint64_t inode) { +#if TOMMY_SIZE_BIT == 64 + return tommy_mulhash_u64(inode); +#else + /* avoid expensive 64-bit multiplications on 32-bit architectures */ return tommy_inthash_u64(inode); +#endif } /** @@ -1025,10 +1030,20 @@ static inline tommy_hash_t file_path_hash(const char* sub) */ static inline tommy_hash_t file_stamp_hash(data_off_t size, int64_t mtime_sec, int mtime_nsec) { + tommy_uint32_t nsec = mtime_nsec; + #if TOMMY_SIZE_BIT == 64 - return tommy_inthash_u64((uint64_t)size ^ tommy_inthash_u64((uint64_t)mtime_sec ^ (uint64_t)(uint32_t)mtime_nsec)); + tommy_uint64_t size_key = size; + tommy_uint64_t sec_key = mtime_sec; + tommy_uint64_t nsec_key = nsec; + + /* valid nanoseconds use 30 bits above contemporary seconds; -1 stays distinct */ + return tommy_mulhash_u64(size_key ^ tommy_mulhash_u64(sec_key ^ (nsec_key << 34))); #else - return tommy_inthash_u32((tommy_uint32_t)size ^ tommy_inthash_u32((tommy_uint32_t)mtime_sec ^ tommy_inthash_u32(mtime_nsec))); + tommy_uint32_t size_key = size; + tommy_uint32_t sec_key = mtime_sec; + + return tommy_mulhash_u32(size_key ^ tommy_mulhash_u32(sec_key) ^ tommy_mulhash_u32(nsec)); #endif } @@ -1556,6 +1571,19 @@ struct snapraid_bucket { void bucket_free(void* void_bucket); +/** + * Compute the hash of a bucket time. + */ +static inline tommy_hash_t bucket_time_hash(time_t time_at) +{ +#if TOMMY_SIZE_BIT == 64 + return tommy_mulhash_u64(time_at); +#else + /* avoid expensive 64-bit multiplications on 32-bit architectures */ + return tommy_inthash_u64(time_at); +#endif +} + /** * Insert an bucket record into the hashtable */