int len) EINA_ARG_NONNULL(1);
static inline int eina_hash_int64(const unsigned long int *pkey,
int len) EINA_ARG_NONNULL(1);
-
+/* http://sites.google.com/site/murmurhash/ */
+static inline int eina_hash_murmur3(const char *key,
+ int len) EINA_ARG_NONNULL(1);
#include "eina_inline_hash.x"
/**
return (int) key;
}
+static inline unsigned int _rotl32(unsigned int x, char r)
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+static inline unsigned int _fmix32(unsigned int h)
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+int
+eina_hash_murmur3(const char *key, int len)
+{
+ const unsigned char * data = (const unsigned char*)key;
+ const int nblocks = len / 4;
+ unsigned int h1 = 0, k1;
+ unsigned int c1 = 0xcc9e2d51;
+ unsigned int c2 = 0x1b873593;
+ const unsigned int * blocks = (const unsigned int *)(data + nblocks*4);
+ int i;
+ const unsigned char *tail;
+
+ for(i = -nblocks; i; i++)
+ {
+ k1 = blocks[i];
+
+ k1 *= c1;
+ k1 = _rotl32(k1, 15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = _rotl32(h1, 13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ tail = (const unsigned char*)(data + nblocks*4);
+
+ 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 = _rotl32(k1, 16);
+ k1 *= c2;
+ h1 ^= k1;
+ }
+
+ h1 ^= len;
+
+ return _fmix32(h1);
+}
#endif
eina_rbtree_delete(root, EINA_RBTREE_FREE_CB(_eina_bench_rbtree_free), NULL);
}
+static void
+eina_bench_lookup_murmur(int request)
+{
+ Eina_Hash *hash = NULL;
+ int *tmp_val;
+ unsigned int i;
+ unsigned int j;
+
+ hash = eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
+ EINA_KEY_CMP(_eina_string_key_cmp),
+ EINA_KEY_HASH(eina_hash_murmur3),
+ free,
+ 8);
+
+ for (i = 0; i < (unsigned int)request; ++i)
+ {
+ char tmp_key[10];
+
+ tmp_val = malloc(sizeof (int));
+
+ if (!tmp_val)
+ continue;
+
+ eina_convert_itoa(i, tmp_key);
+ *tmp_val = i;
+
+ eina_hash_add(hash, tmp_key, tmp_val);
+ }
+
+ srand(time(NULL));
+
+ for (j = 0; j < 200; ++j)
+ for (i = 0; i < (unsigned int)request; ++i)
+ {
+ char tmp_key[10];
+
+ eina_convert_itoa(rand() % request, tmp_key);
+ tmp_val = eina_hash_find(hash, tmp_key);
+ }
+
+ eina_hash_free(hash);
+}
+
#ifdef CITYHASH_BENCH
static void
eina_bench_lookup_cityhash(int request)
eina_benchmark_register(bench, "djb2-lookup-inline",
EINA_BENCHMARK(
eina_bench_lookup_djb2_inline), 10, 10000, 10);
+ eina_benchmark_register(bench, "murmur",
+ EINA_BENCHMARK(
+ eina_bench_lookup_murmur), 10, 10000, 10);
#ifdef CITYHASH_BENCH
eina_benchmark_register(bench, "cityhash",
EINA_BENCHMARK(
- eina_bench_lookup_cityhash), 10, 10000, 10);
+ eina_bench_lookup_cityhash), 10, 10000, 10);
#endif
eina_benchmark_register(bench, "rbtree",
EINA_BENCHMARK(
eina_benchmark_register(bench, "ecore-lookup",
EINA_BENCHMARK(
eina_bench_lookup_ecore), 10, 10000, 10);
+
}