1f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com// lookup3 by Bob Jekins, code is public domain.
2f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
3f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#include "Platform.h"
4f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
5f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
6f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
7f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define mix(a,b,c) \
8f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{ \
9f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  a -= c;  a ^= rot(c, 4);  c += b; \
10f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  b -= a;  b ^= rot(a, 6);  a += c; \
11f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  c -= b;  c ^= rot(b, 8);  b += a; \
12f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  a -= c;  a ^= rot(c,16);  c += b; \
13f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  b -= a;  b ^= rot(a,19);  a += c; \
14f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  c -= b;  c ^= rot(b, 4);  b += a; \
15f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
16f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
17f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com#define final(a,b,c) \
18f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{ \
19f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  c ^= b; c -= rot(b,14); \
20f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  a ^= c; a -= rot(c,11); \
21f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  b ^= a; b -= rot(a,25); \
22f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  c ^= b; c -= rot(b,16); \
23f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  a ^= c; a -= rot(c,4);  \
24f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  b ^= a; b -= rot(a,14); \
25f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  c ^= b; c -= rot(b,24); \
26f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
27f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
28f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comuint32_t lookup3 ( const void * key, int length, uint32_t initval )
29f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
30f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  uint32_t a,b,c;                                          /* internal state */
31f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
32f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  a = b = c = 0xdeadbeef + ((uint32_t)length) + initval;
33f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
34f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  const uint32_t *k = (const uint32_t *)key;         /* read 32-bit chunks */
35f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
36f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */
37f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  while (length > 12)
38f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  {
39f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    a += k[0];
40f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    b += k[1];
41f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    c += k[2];
42f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    mix(a,b,c);
43f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    length -= 12;
44f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    k += 3;
45f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  }
46f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
47f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  switch(length)
48f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  {
49f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
50f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
51f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
52f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
53f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 8 : b+=k[1]; a+=k[0]; break;
54f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
55f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 6 : b+=k[1]&0xffff; a+=k[0]; break;
56f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 5 : b+=k[1]&0xff; a+=k[0]; break;
57f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 4 : a+=k[0]; break;
58f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 3 : a+=k[0]&0xffffff; break;
59f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 2 : a+=k[0]&0xffff; break;
60f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 1 : a+=k[0]&0xff; break;
61f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com    case 0 : { return c; }              /* zero length strings require no mixing */
62f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  }
63f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
64f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  final(a,b,c);
65f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
66f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  return c;
67f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
68f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com
69f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.comvoid lookup3_test ( const void * key, int len, uint32_t seed, void * out )
70f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com{
71f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com  *(uint32_t*)out = lookup3(key,len,seed);
72f3b789787b93945c974e2cc517b7dc352b28354etanjent@gmail.com}
73