Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > Hash_impl
annotate MurmurHash2.c @ 28:18a72865dd78
marked TODO: doubleTableSize corrupts mem
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Wed, 06 Mar 2013 14:35:01 +0100 |
| parents | 1218b245530c |
| children |
| rev | line source |
|---|---|
| Me@14 | 1 |
| Me@14 | 2 /*This file is sample code pulled off the web -- NOT part of the compiled code |
| Me@14 | 3 * make sure it doesn't get included in makefile 'cause it doesn't compile |
| Me@14 | 4 */ |
| Me@14 | 5 |
| Me@14 | 6 //----------------------------------------------------------------------------- |
| Me@14 | 7 // MurmurHash2, by Austin Appleby |
| Me@14 | 8 |
| Me@14 | 9 // Note - This code makes a few assumptions about how your machine behaves - |
| Me@14 | 10 |
| Me@14 | 11 // 1. We can read a 4-byte value from any address without crashing |
| Me@14 | 12 // 2. sizeof(int) == 4 |
| Me@14 | 13 |
| Me@14 | 14 // And it has a few limitations - |
| Me@14 | 15 |
| Me@14 | 16 // 1. It will not work incrementally. |
| Me@14 | 17 // 2. It will not produce the same results on little-endian and big-endian |
| Me@14 | 18 // machines. |
| Me@14 | 19 |
| Me@14 | 20 unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed ) |
| Me@14 | 21 { |
| Me@14 | 22 // 'm' and 'r' are mixing constants generated offline. |
| Me@14 | 23 // They're not really 'magic', they just happen to work well. |
| Me@14 | 24 |
| Me@14 | 25 const unsigned int m = 0x5bd1e995; |
| Me@14 | 26 const int r = 24; |
| Me@14 | 27 |
| Me@14 | 28 // Initialize the hash to a 'random' value |
| Me@14 | 29 |
| Me@14 | 30 unsigned int h = seed ^ len; |
| Me@14 | 31 |
| Me@14 | 32 // Mix 4 bytes at a time into the hash |
| Me@14 | 33 |
| Me@14 | 34 const unsigned char * data = (const unsigned char *)key; |
| Me@14 | 35 |
| Me@14 | 36 while(len >= 4) |
| Me@14 | 37 { |
| Me@14 | 38 unsigned int k = *(unsigned int *)data; |
| Me@14 | 39 |
| Me@14 | 40 k *= m; |
| Me@14 | 41 k ^= k >> r; |
| Me@14 | 42 k *= m; |
| Me@14 | 43 |
| Me@14 | 44 h *= m; |
| Me@14 | 45 h ^= k; |
| Me@14 | 46 |
| Me@14 | 47 data += 4; |
| Me@14 | 48 len -= 4; |
| Me@14 | 49 } |
| Me@14 | 50 |
| Me@14 | 51 // Handle the last few bytes of the input array |
| Me@14 | 52 |
| Me@14 | 53 switch(len) |
| Me@14 | 54 { |
| Me@14 | 55 case 3: h ^= data[2] << 16; |
| Me@14 | 56 case 2: h ^= data[1] << 8; |
| Me@14 | 57 case 1: h ^= data[0]; |
| Me@14 | 58 h *= m; |
| Me@14 | 59 }; |
| Me@14 | 60 |
| Me@14 | 61 // Do a few final mixes of the hash to ensure the last few |
| Me@14 | 62 // bytes are well-incorporated. |
| Me@14 | 63 |
| Me@14 | 64 h ^= h >> 13; |
| Me@14 | 65 h *= m; |
| Me@14 | 66 h ^= h >> 15; |
| Me@14 | 67 |
| Me@14 | 68 return h; |
| Me@14 | 69 } |
