1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
7 Murmurhash from http://sites.google.com/site/murmurhash/
9 All code is released to the public domain. For business purposes, Murmurhash
10 is under the MIT license.
12 #include "murmurhash.h"
13 #include "port/lang.h"
15 #if defined(__x86_64__)
17 // -------------------------------------------------------------------
19 // The same caveats as 32-bit MurmurHash2 apply here - beware of alignment
20 // and endian-ness issues if used across multiple platforms.
22 // 64-bit hash for 64-bit platforms
24 #ifdef ROCKSDB_UBSAN_RUN
25 #if defined(__clang__)
26 __attribute__((__no_sanitize__("alignment")))
27 #elif defined(__GNUC__)
28 __attribute__((__no_sanitize_undefined__
))
31 uint64_t MurmurHash64A ( const void * key
, int len
, unsigned int seed
)
33 const uint64_t m
= 0xc6a4a7935bd1e995;
36 uint64_t h
= seed
^ (len
* m
);
38 const uint64_t * data
= (const uint64_t *)key
;
39 const uint64_t * end
= data
+ (len
/8);
53 const unsigned char * data2
= (const unsigned char*)data
;
57 case 7: h
^= ((uint64_t)data2
[6]) << 48; FALLTHROUGH_INTENDED
;
58 case 6: h
^= ((uint64_t)data2
[5]) << 40; FALLTHROUGH_INTENDED
;
59 case 5: h
^= ((uint64_t)data2
[4]) << 32; FALLTHROUGH_INTENDED
;
60 case 4: h
^= ((uint64_t)data2
[3]) << 24; FALLTHROUGH_INTENDED
;
61 case 3: h
^= ((uint64_t)data2
[2]) << 16; FALLTHROUGH_INTENDED
;
62 case 2: h
^= ((uint64_t)data2
[1]) << 8; FALLTHROUGH_INTENDED
;
63 case 1: h
^= ((uint64_t)data2
[0]);
74 #elif defined(__i386__)
76 // -------------------------------------------------------------------
78 // Note - This code makes a few assumptions about how your machine behaves -
80 // 1. We can read a 4-byte value from any address without crashing
81 // 2. sizeof(int) == 4
83 // And it has a few limitations -
85 // 1. It will not work incrementally.
86 // 2. It will not produce the same results on little-endian and big-endian
89 unsigned int MurmurHash2 ( const void * key
, int len
, unsigned int seed
)
91 // 'm' and 'r' are mixing constants generated offline.
92 // They're not really 'magic', they just happen to work well.
94 const unsigned int m
= 0x5bd1e995;
97 // Initialize the hash to a 'random' value
99 unsigned int h
= seed
^ len
;
101 // Mix 4 bytes at a time into the hash
103 const unsigned char * data
= (const unsigned char *)key
;
107 unsigned int k
= *(unsigned int *)data
;
120 // Handle the last few bytes of the input array
124 case 3: h
^= data
[2] << 16; FALLTHROUGH_INTENDED
;
125 case 2: h
^= data
[1] << 8; FALLTHROUGH_INTENDED
;
126 case 1: h
^= data
[0];
130 // Do a few final mixes of the hash to ensure the last few
131 // bytes are well-incorporated.
142 // -------------------------------------------------------------------
144 // Same as MurmurHash2, but endian- and alignment-neutral.
145 // Half the speed though, alas.
147 unsigned int MurmurHashNeutral2 ( const void * key
, int len
, unsigned int seed
)
149 const unsigned int m
= 0x5bd1e995;
152 unsigned int h
= seed
^ len
;
154 const unsigned char * data
= (const unsigned char *)key
;
178 case 3: h
^= data
[2] << 16; FALLTHROUGH_INTENDED
;
179 case 2: h
^= data
[1] << 8; FALLTHROUGH_INTENDED
;
180 case 1: h
^= data
[0];