-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathabcemurmur.h
92 lines (80 loc) · 1.84 KB
/
abcemurmur.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef _ABCE_MURMUR_H_
#define _ABCE_MURMUR_H_
#include <stdint.h>
#include <stddef.h>
#include "abcehdr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct abce_murmurctx {
uint32_t hash;
uint32_t len;
};
#define ABCE_MURMURCTX_INITER(seed) \
{ \
.hash = (seed), \
.len = 0, \
}
static inline void abce_murmurctx_feed32(struct abce_murmurctx *ctx, uint32_t val)
{
uint32_t c1 = 0xcc9e2d51;
uint32_t c2 = 0x1b873593;
uint32_t m = 5;
uint32_t n = 0xe6546b64;
uint32_t k = val;
uint32_t hash = ctx->hash;
k = k*c1;
k = (k << 15) | (k >> 17);
k = k*c2;
hash = hash ^ k;
hash = (hash << 13) | (hash >> 19);
hash = hash*m + n;
ctx->len += 4;
ctx->hash = hash;
}
static inline void abce_murmurctx_feed_buf(
struct abce_murmurctx *ctx, const void *buf, size_t sz)
{
const char *cbuf = (const char*)buf;
size_t i = 0;
struct abce_murmurctx ctx2 = *ctx;
while (i < (sz/4)*4)
{
abce_murmurctx_feed32(&ctx2, abce_hdr_get32h(&cbuf[i]));
i += 4;
}
while (i < sz)
{
abce_murmurctx_feed32(&ctx2, abce_hdr_get8h(&cbuf[i]));
i += 1;
}
*ctx = ctx2;
}
static inline uint32_t abce_murmurctx_get(struct abce_murmurctx *ctx)
{
uint32_t hash;
hash = ctx->hash;
hash = hash ^ ctx->len;
hash = hash ^ (hash >> 16);
hash = hash * 0x85ebca6b;
hash = hash ^ (hash >> 13);
hash = hash * 0xc2b2ae35;
hash = hash ^ (hash >> 16);
return hash;
}
static inline uint32_t abce_murmur32(uint32_t seed, uint32_t val)
{
struct abce_murmurctx ctx = ABCE_MURMURCTX_INITER(seed);
abce_murmurctx_feed32(&ctx, val);
return abce_murmurctx_get(&ctx);
}
static inline uint32_t abce_murmur_buf(uint32_t seed, const void *buf, size_t sz)
{
struct abce_murmurctx ctx = ABCE_MURMURCTX_INITER(seed);
abce_murmurctx_feed_buf(&ctx, buf, sz);
return abce_murmurctx_get(&ctx);
}
#ifdef __cplusplus
};
#endif
#endif