1 | //----------------------------------------------------------------------------- |
2 | // MurmurHash2 was written by Austin Appleby, and is placed in the public |
3 | // domain. The author hereby disclaims copyright to this source code. |
4 | //----------------------------------------------------------------------------- |
5 | // LibSass only needs MurmurHash2, so we made this header only |
6 | //----------------------------------------------------------------------------- |
7 | |
8 | #ifndef _MURMURHASH2_H_ |
9 | #define _MURMURHASH2_H_ |
10 | |
11 | //----------------------------------------------------------------------------- |
12 | // Platform-specific functions and macros |
13 | |
14 | // Microsoft Visual Studio |
15 | |
16 | #if defined(_MSC_VER) && (_MSC_VER < 1600) |
17 | |
18 | typedef unsigned char uint8_t; |
19 | typedef unsigned int uint32_t; |
20 | typedef unsigned __int64 uint64_t; |
21 | |
22 | // Other compilers |
23 | |
24 | #else // defined(_MSC_VER) |
25 | |
26 | #include <stdint.h> |
27 | |
28 | #endif // !defined(_MSC_VER) |
29 | |
30 | //----------------------------------------------------------------------------- |
31 | |
32 | inline uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed ) |
33 | { |
34 | // 'm' and 'r' are mixing constants generated offline. |
35 | // They're not really 'magic', they just happen to work well. |
36 | |
37 | const uint32_t m = 0x5bd1e995; |
38 | const int r = 24; |
39 | |
40 | // Initialize the hash to a 'random' value |
41 | |
42 | uint32_t h = seed ^ len; |
43 | |
44 | // Mix 4 bytes at a time into the hash |
45 | |
46 | const unsigned char * data = (const unsigned char *)key; |
47 | |
48 | while(len >= 4) |
49 | { |
50 | uint32_t k = *(uint32_t*)data; |
51 | |
52 | k *= m; |
53 | k ^= k >> r; |
54 | k *= m; |
55 | |
56 | h *= m; |
57 | h ^= k; |
58 | |
59 | data += 4; |
60 | len -= 4; |
61 | } |
62 | |
63 | // Handle the last few bytes of the input array |
64 | |
65 | switch(len) |
66 | { |
67 | case 3: |
68 | h ^= data[2] << 16; |
69 | /* fall through */ |
70 | case 2: |
71 | h ^= data[1] << 8; |
72 | /* fall through */ |
73 | case 1: |
74 | h ^= data[0]; |
75 | h *= m; |
76 | }; |
77 | |
78 | // Do a few final mixes of the hash to ensure the last few |
79 | // bytes are well-incorporated. |
80 | |
81 | h ^= h >> 13; |
82 | h *= m; |
83 | h ^= h >> 15; |
84 | |
85 | return h; |
86 | } |
87 | |
88 | //----------------------------------------------------------------------------- |
89 | |
90 | #endif // _MURMURHASH2_H_ |
91 | |
92 | |