1f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include "Platform.h"
2f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include <stdio.h> // for NULL
3f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
4f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/* By Paul Hsieh (C) 2004, 2005.  Covered under the Paul Hsieh derivative
5f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com   license. See:
6f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com   http://www.azillionmonkeys.com/qed/weblicense.html for license details.
7f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
8f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com   http://www.azillionmonkeys.com/qed/hash.html */
9f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
10f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com/*
11f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#undef get16bits
12f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
13f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
14f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define get16bits(d) (*((const uint16_t *) (d)))
15f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#endif
16f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
17f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#if !defined (get16bits)
18f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
19f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com                       +(uint32_t)(((const uint8_t *)(d))[0]) )
20f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#endif
21f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com*/
22f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
23f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comFORCE_INLINE uint16_t get16bits ( const void * p )
24f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
25f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  return *(const uint16_t*)p;
26f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
27f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
28f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comuint32_t SuperFastHash (const signed char * data, int len) {
29f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comuint32_t hash = 0, tmp;
30f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comint rem;
31f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
32f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  if (len <= 0 || data == NULL) return 0;
33f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
34f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  rem = len & 3;
35f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  len >>= 2;
36f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
37f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  /* Main loop */
38f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  for (;len > 0; len--) {
39f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    hash  += get16bits (data);
40f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    tmp    = (get16bits (data+2) << 11) ^ hash;
41f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    hash   = (hash << 16) ^ tmp;
42f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    data  += 2*sizeof (uint16_t);
43f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    hash  += hash >> 11;
44f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  }
45f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
46f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  /* Handle end cases */
47f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  switch (rem) {
48f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 3:	hash += get16bits (data);
49f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash ^= hash << 16;
50f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash ^= data[sizeof (uint16_t)] << 18;
51f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash += hash >> 11;
52f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        break;
53f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 2:	hash += get16bits (data);
54f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash ^= hash << 11;
55f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash += hash >> 17;
56f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        break;
57f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 1: hash += *data;
58f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash ^= hash << 10;
59f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com        hash += hash >> 1;
60f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  }
61f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
62f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  /* Force "avalanching" of final 127 bits */
63f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  hash ^= hash << 3;
64f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  hash += hash >> 5;
65f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  hash ^= hash << 4;
66f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  hash += hash >> 17;
67f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  hash ^= hash << 25;
68f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  hash += hash >> 6;
69f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
70f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  return hash;
71f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
72f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
73f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid SuperFastHash     ( const void * key, int len, uint32_t /*seed*/, void * out )
74f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
75f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  *(uint32_t*)out = SuperFastHash((const signed char*)key,len);
76f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
77