blob: 38d030da7f4cd5b3f6b197e6f9cd2fe159595b25 [file] [log] [blame]
tanjent@gmail.com9808b172011-03-20 04:25:41 +00001#include "Platform.h"
tanjent@gmail.comb39a5f02011-03-20 04:29:19 +00002#include <stdio.h> // for NULL
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00003
4/* By Paul Hsieh (C) 2004, 2005. Covered under the Paul Hsieh derivative
5 license. See:
6 http://www.azillionmonkeys.com/qed/weblicense.html for license details.
7
8 http://www.azillionmonkeys.com/qed/hash.html */
9
aappleby@google.comcc592162011-04-08 20:49:43 +000010/*
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000011#undef get16bits
12#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
13 || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
14#define get16bits(d) (*((const uint16_t *) (d)))
15#endif
16
17#if !defined (get16bits)
18#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
19 +(uint32_t)(((const uint8_t *)(d))[0]) )
20#endif
aappleby@google.comcc592162011-04-08 20:49:43 +000021*/
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000022
aappleby@google.comcc592162011-04-08 20:49:43 +000023FORCE_INLINE uint16_t get16bits ( const void * p )
24{
25 return *(const uint16_t*)p;
26}
27
28uint32_t SuperFastHash (const signed char * data, int len) {
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000029uint32_t hash = 0, tmp;
30int rem;
31
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000032 if (len <= 0 || data == NULL) return 0;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000033
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000034 rem = len & 3;
35 len >>= 2;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000036
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000037 /* Main loop */
38 for (;len > 0; len--) {
39 hash += get16bits (data);
40 tmp = (get16bits (data+2) << 11) ^ hash;
41 hash = (hash << 16) ^ tmp;
42 data += 2*sizeof (uint16_t);
43 hash += hash >> 11;
44 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000045
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000046 /* Handle end cases */
47 switch (rem) {
48 case 3: hash += get16bits (data);
49 hash ^= hash << 16;
50 hash ^= data[sizeof (uint16_t)] << 18;
51 hash += hash >> 11;
52 break;
53 case 2: hash += get16bits (data);
54 hash ^= hash << 11;
55 hash += hash >> 17;
56 break;
57 case 1: hash += *data;
58 hash ^= hash << 10;
59 hash += hash >> 1;
60 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000061
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000062 /* Force "avalanching" of final 127 bits */
63 hash ^= hash << 3;
64 hash += hash >> 5;
65 hash ^= hash << 4;
66 hash += hash >> 17;
67 hash ^= hash << 25;
68 hash += hash >> 6;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000069
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000070 return hash;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000071}
72
73void SuperFastHash ( const void * key, int len, uint32_t /*seed*/, void * out )
74{
aappleby@google.comcc592162011-04-08 20:49:43 +000075 *(uint32_t*)out = SuperFastHash((const signed char*)key,len);
76}