diff --git a/include/common/hash.h b/include/common/hash.h index 7039ba507..16876c29a 100644 --- a/include/common/hash.h +++ b/include/common/hash.h @@ -25,5 +25,6 @@ unsigned int hash_djb2(const char *key, int len); unsigned int hash_wt6(const char *key, int len); unsigned int hash_sdbm(const char *key, int len); +unsigned int hash_crc32(const char *key, int len); #endif /* _COMMON_HASH_H_ */ diff --git a/src/hash.c b/src/hash.c index aa236cbb0..43ba11c7c 100644 --- a/src/hash.c +++ b/src/hash.c @@ -85,4 +85,23 @@ unsigned int hash_sdbm(const char *key, int len) return hash; } +/* Small yet efficient CRC32 calculation loosely inspired from crc32b found + * here : http://www.hackersdelight.org/hdcodetxt/crc.c.txt + * The magic value represents the polynom with one bit per exponent. Much + * faster table-based versions exist but are pointless for our usage here, + * this hash already sustains gigabit speed which is far faster than what + * we'd ever need. Better preserve the CPU's cache instead. + */ +unsigned int hash_crc32(const char *key, int len) +{ + unsigned int hash; + int bit; + hash = ~0; + while (len--) { + hash ^= *key++; + for (bit = 0; bit < 8; bit++) + hash = (hash >> 1) ^ ((hash & 1) ? 0xedb88320 : 0); + } + return ~hash; +}