[Mesa-dev] [PATCH 7/8] util: Add murmur3 hashing function
Thomas Helland
thomashelland90 at gmail.com
Sat Feb 28 04:53:53 PST 2015
Copy-pasta from the wikipedia article.
Results from oprofile on a shader-db run:
mesa_hash_data 3.25 ---> 3.11
hash_table_insert 2.52 ---> 2.52
hash_table_search 2.64 ---> 2.64
set_add 1.65 ---> 1.74
set_search 2.07 ---> 2.08
runtime 160 ---> 160
---
src/util/hash_table.c | 5 ++---
src/util/hash_table.h | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/src/util/hash_table.c b/src/util/hash_table.c
index 8216869..f2b8cf6 100644
--- a/src/util/hash_table.c
+++ b/src/util/hash_table.c
@@ -436,8 +436,7 @@ _mesa_hash_table_random_entry(struct hash_table *ht,
uint32_t
_mesa_hash_data(const void *data, size_t size)
{
- return _mesa_fnv32_1a_accumulate_block(_mesa_fnv32_1a_offset_bias,
- data, size);
+ return murmur3_32(data, size, _mesa_fnv32_1a_offset_bias);
}
/** FNV-1a string hash implementation */
@@ -447,7 +446,7 @@ _mesa_hash_string(const char *key)
uint32_t hash = _mesa_fnv32_1a_offset_bias;
while (*key != 0) {
- hash = _mesa_fnv32_1a_accumulate(hash, *key);
+ hash = _mesa_murmur3_32(hash, *key);
key++;
}
diff --git a/src/util/hash_table.h b/src/util/hash_table.h
index 6d41338..288e205 100644
--- a/src/util/hash_table.h
+++ b/src/util/hash_table.h
@@ -119,6 +119,60 @@ _mesa_fnv32_1a_accumulate_block(uint32_t hash, const void *data, size_t size)
#define _mesa_fnv32_1a_accumulate(hash, expr) \
_mesa_fnv32_1a_accumulate_block(hash, &(expr), sizeof(expr))
+#define _mesa_murmur3_32(hash, expr) \
+ murmur3_32(&(expr), sizeof(expr), hash)
+
+static inline
+uint32_t murmur3_32(const char *key, uint32_t len, uint32_t seed) {
+ static const uint32_t c1 = 0xcc9e2d51;
+ static const uint32_t c2 = 0x1b873593;
+ static const uint32_t r1 = 15;
+ static const uint32_t r2 = 13;
+ static const uint32_t m = 5;
+ static const uint32_t n = 0xe6546b64;
+
+ uint32_t hash = seed;
+
+ const int nblocks = len / 4;
+ const uint32_t *blocks = (const uint32_t *) key;
+ int i;
+ for (i = 0; i < nblocks; i++) {
+ uint32_t k = blocks[i];
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+
+ hash ^= k;
+ hash = ((hash << r2) | (hash >> (32 - r2))) * m + n;
+ }
+
+ const uint8_t *tail = (const uint8_t *) (key + nblocks * 4);
+ uint32_t k1 = 0;
+
+ switch (len & 3) {
+ case 3:
+ k1 ^= tail[2] << 16;
+ case 2:
+ k1 ^= tail[1] << 8;
+ case 1:
+ k1 ^= tail[0];
+
+ k1 *= c1;
+ k1 = (k1 << r1) | (k1 >> (32 - r1));
+ k1 *= c2;
+ hash ^= k1;
+ }
+
+ hash ^= len;
+ hash ^= (hash >> 16);
+ hash *= 0x85ebca6b;
+ hash ^= (hash >> 13);
+ hash *= 0xc2b2ae35;
+ hash ^= (hash >> 16);
+
+ return hash;
+}
+
/**
* This foreach function is safe against deletion (which just replaces
* an entry's data with the deleted marker), but not against insertion
--
2.2.1
More information about the mesa-dev
mailing list