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