]> git.proxmox.com Git - ceph.git/blame - ceph/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_util_hashbytes.c
import 12.2.13 release
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.8.0 / src-separate / duk_util_hashbytes.c
CommitLineData
7c673cae
FG
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
b9c3bfeb 12#if defined(DUK_USE_STRHASH_DENSE)
7c673cae
FG
13/* 'magic' constants for Murmurhash2 */
14#define DUK__MAGIC_M ((duk_uint32_t) 0x5bd1e995UL)
15#define DUK__MAGIC_R 24
16
17DUK_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
b9c3bfeb 27 duk_uint32_t k = *((const duk_uint32_t *) (const void *) data);
7c673cae
FG
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}
b9c3bfeb 57#endif /* DUK_USE_STRHASH_DENSE */