|
@@ -22,40 +22,37 @@
|
|
|
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
|
|
* Copyright (C) 2004-2008 by Paul Hsieh
|
|
|
*/
|
|
|
+static inline uint16_t get_le16(const uint8_t *d) {
|
|
|
+ return (((uint16_t)d[1]) << 8) | d[0];
|
|
|
+}
|
|
|
|
|
|
-static uint32_t sfh_hash(const char *data, int len)
|
|
|
+static uint32_t sfh_hash(const uint8_t *data, int len)
|
|
|
{
|
|
|
uint32_t hash = len, tmp;
|
|
|
- int rem;
|
|
|
-
|
|
|
- if (len <= 0 || data == NULL) return 0;
|
|
|
-
|
|
|
- rem = len & 3;
|
|
|
- len >>= 2;
|
|
|
|
|
|
/* Main loop */
|
|
|
- for (;len > 0; len--) {
|
|
|
- hash += sfh_get16(data);
|
|
|
- tmp = (sfh_get16(data+2) << 11) ^ hash;
|
|
|
+ for (; len > 3; len -= 4) {
|
|
|
+ hash += get_le16(data);
|
|
|
+ tmp = (get_le16(data+2) << 11) ^ hash;
|
|
|
hash = (hash << 16) ^ tmp;
|
|
|
- data += 2*sizeof(uint16_t);
|
|
|
+ data += 4;
|
|
|
hash += hash >> 11;
|
|
|
}
|
|
|
|
|
|
/* Handle end cases */
|
|
|
- switch (rem) {
|
|
|
- case 3: hash += sfh_get16(data);
|
|
|
- hash ^= hash << 16;
|
|
|
- hash ^= data[sizeof(uint16_t)] << 18;
|
|
|
- hash += hash >> 11;
|
|
|
- break;
|
|
|
- case 2: hash += sfh_get16(data);
|
|
|
- hash ^= hash << 11;
|
|
|
- hash += hash >> 17;
|
|
|
- break;
|
|
|
- case 1: hash += *data;
|
|
|
- hash ^= hash << 10;
|
|
|
- hash += hash >> 1;
|
|
|
+ switch (len) {
|
|
|
+ case 3: hash += get_le16(data);
|
|
|
+ hash ^= hash << 16;
|
|
|
+ hash ^= data[2] << 18;
|
|
|
+ hash += hash >> 11;
|
|
|
+ break;
|
|
|
+ case 2: hash += get_le16(data);
|
|
|
+ hash ^= hash << 11;
|
|
|
+ hash += hash >> 17;
|
|
|
+ break;
|
|
|
+ case 1: hash += *data;
|
|
|
+ hash ^= hash << 10;
|
|
|
+ hash += hash >> 1;
|
|
|
}
|
|
|
|
|
|
/* Force "avalanching" of final 127 bits */
|