]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_util_hashbytes.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.8.0 / src-separate / duk_util_hashbytes.c
1 /*
2 * Hash function duk_util_hashbytes().
3 *
4 * Currently, 32-bit MurmurHash2.
5 *
6 * Don't rely on specific hash values; hash function may be endianness
7 * dependent, for instance.
8 */
9
10 #include "duk_internal.h"
11
12 #if defined(DUK_USE_STRHASH_DENSE)
13 /* 'magic' constants for Murmurhash2 */
14 #define DUK__MAGIC_M ((duk_uint32_t) 0x5bd1e995UL)
15 #define DUK__MAGIC_R 24
16
17 DUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) {
18 duk_uint32_t h = seed ^ ((duk_uint32_t) len);
19
20 while (len >= 4) {
21 /* Portability workaround is required for platforms without
22 * unaligned access. The replacement code emulates little
23 * endian access even on big endian architectures, which is
24 * OK as long as it is consistent for a build.
25 */
26 #ifdef DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS
27 duk_uint32_t k = *((const duk_uint32_t *) (const void *) data);
28 #else
29 duk_uint32_t k = ((duk_uint32_t) data[0]) |
30 (((duk_uint32_t) data[1]) << 8) |
31 (((duk_uint32_t) data[2]) << 16) |
32 (((duk_uint32_t) data[3]) << 24);
33 #endif
34
35 k *= DUK__MAGIC_M;
36 k ^= k >> DUK__MAGIC_R;
37 k *= DUK__MAGIC_M;
38 h *= DUK__MAGIC_M;
39 h ^= k;
40 data += 4;
41 len -= 4;
42 }
43
44 switch (len) {
45 case 3: h ^= data[2] << 16;
46 case 2: h ^= data[1] << 8;
47 case 1: h ^= data[0];
48 h *= DUK__MAGIC_M;
49 }
50
51 h ^= h >> 13;
52 h *= DUK__MAGIC_M;
53 h ^= h >> 15;
54
55 return h;
56 }
57 #endif /* DUK_USE_STRHASH_DENSE */