2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
16 #include "libhashkit/hashkitcon.h"
18 #include "libhashkit/murmur3.h"
20 //-----------------------------------------------------------------------------
21 // Platform-specific functions and macros
24 # define FORCE_INLINE __attribute__((always_inline)) inline
26 # define FORCE_INLINE inline
29 static FORCE_INLINE
uint32_t rotl32(uint32_t x
, int8_t r
) {
30 return (x
<< r
) | (x
>> (32 - r
));
33 #define ROTL32(x, y) rotl32(x, y)
35 //-----------------------------------------------------------------------------
36 // Block read - if your platform needs to do endian-swapping or can only
37 // handle aligned reads, do the conversion here
42 static inline T
getblock(const T
*blocks
, int i
) {
44 memcpy(&b
, ((const uint8_t *) blocks
) + i
* sizeof(T
), sizeof(T
));
48 //-----------------------------------------------------------------------------
49 // Finalization mix - force all bits of a hash block to avalanche
51 static FORCE_INLINE
uint32_t fmix32(uint32_t h
) {
61 //-----------------------------------------------------------------------------
63 void MurmurHash3_x86_32(const void *key
, int len
, uint32_t seed
, void *out
) {
64 const uint8_t *data
= (const uint8_t *) key
;
65 const int nblocks
= len
/ 4;
70 uint32_t c1
= 0xcc9e2d51;
71 uint32_t c2
= 0x1b873593;
76 const uint32_t *blocks
= (const uint32_t *) (data
+ nblocks
* 4);
78 for (i
= -nblocks
; i
; i
++) {
79 uint32_t k1
= getblock(blocks
, i
);
90 h1
= h1
* 5 + 0xe6546b64;
96 const uint8_t *tail
= (const uint8_t *) (data
+ nblocks
* 4);
99 memcpy(&k1
, tail
, len
& 3);
101 k1
= BYTESWAP_32(k1
);
116 *(uint32_t *) out
= h1
;