summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas De Marchi <lucas.demarchi@intel.com>2013-08-13 10:30:28 -0300
committerLucas De Marchi <lucas.demarchi@intel.com>2013-09-20 14:33:38 -0500
commit05f7fdacf572321564b6fe8d1f9b262737e1b6ec (patch)
tree4f98b43984ef887b4bf3a18c8b51967e7a13df98
parent8f67ab5340bdba008503019d6941c06e5de534af (diff)
downloadkmod-05f7fdacf572321564b6fe8d1f9b262737e1b6ec.tar.gz
Add hash functions for test
-rw-r--r--configure.ac1
-rw-r--r--libkmod/libkmod-hash.c147
2 files changed, 147 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index e7416f6..d1fa577 100644
--- a/configure.ac
+++ b/configure.ac
@@ -179,6 +179,7 @@ CC_CHECK_FLAGS_APPEND(with_cflags, [CFLAGS], [\
-Wuninitialized \
-fno-common \
-fdiagnostics-show-option \
+ -mcrc32 \
-fvisibility=hidden \
-ffunction-sections \
-fdata-sections])
diff --git a/libkmod/libkmod-hash.c b/libkmod/libkmod-hash.c
index c751d2d..dfe596f 100644
--- a/libkmod/libkmod-hash.c
+++ b/libkmod/libkmod-hash.c
@@ -26,6 +26,24 @@
#include <string.h>
#include <errno.h>
+static _always_inline_ unsigned long long native_read_tsc(void)
+{
+ unsigned hi, lo;
+ asm volatile ("lfence;\n"
+ "rdtsc;\n"
+ : "=a"(lo), "=d"(hi));
+ return (unsigned long long)((lo) | ((uint64_t)(hi) << 32));
+}
+
+static inline unsigned long long get_cycles(unsigned long long last)
+{
+ unsigned long long ret;
+
+ ret = native_read_tsc();
+
+ return ret - last;
+}
+
struct hash_entry {
const char *key;
const void *value;
@@ -87,7 +105,134 @@ void hash_free(struct hash *hash)
free(hash);
}
-static inline unsigned int hash_superfast(const char *key, unsigned int len)
+static _always_inline_ uint32_t rotl32 ( uint32_t x, int8_t r )
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+#define ROTL32(x,y) rotl32(x,y)
+
+static _always_inline_ uint32_t getblock32 ( const uint32_t * p, int i )
+{
+ return p[i];
+}
+
+static inline unsigned int MurmurHash3_x86_32(const void * key, unsigned int len)
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 4;
+
+ uint32_t h1 = 0;
+
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ const uint8_t * tail;
+ uint32_t k1;
+
+ //----------
+ // body
+
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
+
+ for(int i = -nblocks; i; i++)
+ {
+ k1 = getblock32(blocks,i);
+
+ k1 *= c1;
+ k1 = ROTL32(k1,15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = ROTL32(h1,13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ //----------
+ // tail
+
+ tail = (const uint8_t*)(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,15); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len;
+
+ h1 ^= h1 >> 16;
+ h1 *= 0x85ebca6b;
+ h1 ^= h1 >> 13;
+ h1 *= 0xc2b2ae35;
+ h1 ^= h1 >> 16;
+
+ return h1;
+}
+
+static inline unsigned int hash_crc32c_hw(const void *key, unsigned int len)
+{
+ const char* p_buf = (const char*) key;
+ unsigned int crc = 0;
+ unsigned int i;
+
+ for (i = 0; i < len / sizeof(uint64_t); i++) {
+ crc = __builtin_ia32_crc32di(crc, *(uint64_t*) p_buf);
+ p_buf += sizeof(uint64_t);
+ }
+
+ len &= sizeof(uint64_t) - 1;
+
+ switch (len) {
+ case 7:
+ crc = __builtin_ia32_crc32qi(crc, *p_buf++);
+ case 6:
+ crc = __builtin_ia32_crc32hi(crc, *(uint16_t*) p_buf);
+ p_buf += 2;
+ // case 5 is below: 4 + 1
+ case 4:
+ crc = __builtin_ia32_crc32si(crc, *(uint32_t*) p_buf);
+ break;
+ case 3:
+ crc = __builtin_ia32_crc32qi(crc, *p_buf++);
+ case 2:
+ crc = __builtin_ia32_crc32hi(crc, *(uint16_t*) p_buf);
+ break;
+ case 5:
+ crc = __builtin_ia32_crc32si(crc, *(uint32_t*) p_buf);
+ p_buf += 4;
+ case 1:
+ crc = __builtin_ia32_crc32qi(crc, *p_buf);
+ break;
+ case 0:
+ break;
+ }
+
+ return crc;
+
+}
+
+static inline unsigned int MurmurHash3_x86_32(const void *key, unsigned int len)
+{
+ unsigned hash = 5381;
+ const signed char *c;
+
+ /* DJB's hash function */
+
+ for (c = key; *c; c++)
+ hash = (hash << 5) + hash + (unsigned) *c;
+
+ return hash;
+}
+
+static inline unsigned int hash_paul(const char *key, unsigned int len)
{
/* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html)
* used by WebCore (http://webkit.org/blog/8/hashtables-part-2/)