glusterfs: update for new API
[fio.git] / lib / bloom.c
CommitLineData
652ae149 1#include <stdlib.h>
652ae149
JA
2
3#include "bloom.h"
4#include "../hash.h"
899834b5 5#include "../crc/xxhash.h"
f83ffd02 6#include "../crc/murmur3.h"
78583f91
JA
7#include "../crc/crc32c.h"
8#include "../crc/fnv.h"
652ae149
JA
9
10struct bloom {
11 uint64_t nentries;
12
13 uint32_t *map;
14};
15
16#define BITS_PER_INDEX (sizeof(uint32_t) * 8)
17#define BITS_INDEX_MASK (BITS_PER_INDEX - 1)
18
899834b5
JA
19struct bloom_hash {
20 unsigned int seed;
21 uint32_t (*fn)(const void *, uint32_t, uint32_t);
22};
23
78583f91
JA
24static uint32_t bloom_crc32c(const void *buf, uint32_t len, uint32_t seed)
25{
26 return fio_crc32c(buf, len);
27}
28
29static uint32_t bloom_fnv(const void *buf, uint32_t len, uint32_t seed)
30{
31 return fnv(buf, len, seed);
32}
33
34#define BLOOM_SEED 0x8989
35
a89ba4b1 36static struct bloom_hash hashes[] = {
899834b5 37 {
78583f91 38 .seed = BLOOM_SEED,
899834b5
JA
39 .fn = jhash,
40 },
41 {
78583f91 42 .seed = BLOOM_SEED,
899834b5
JA
43 .fn = XXH32,
44 },
45 {
78583f91 46 .seed = BLOOM_SEED,
9f0e365d 47 .fn = murmurhash3,
899834b5 48 },
78583f91
JA
49 {
50 .seed = BLOOM_SEED,
51 .fn = bloom_crc32c,
52 },
53 {
54 .seed = BLOOM_SEED,
55 .fn = bloom_fnv,
56 },
899834b5
JA
57};
58
78583f91 59#define N_HASHES 5
652ae149
JA
60
61struct bloom *bloom_new(uint64_t entries)
62{
63 struct bloom *b;
64 size_t no_uints;
65
214e2d56 66 crc32c_arm64_probe();
78583f91
JA
67 crc32c_intel_probe();
68
652ae149
JA
69 b = malloc(sizeof(*b));
70 b->nentries = entries;
71 no_uints = (entries + BITS_PER_INDEX - 1) / BITS_PER_INDEX;
72 b->map = calloc(no_uints, sizeof(uint32_t));
73 if (!b->map) {
74 free(b);
75 return NULL;
76 }
77
78 return b;
79}
80
81void bloom_free(struct bloom *b)
82{
83 free(b->map);
84 free(b);
85}
86
0a301e93 87static bool __bloom_check(struct bloom *b, const void *data, unsigned int len,
c0d75983 88 bool set)
652ae149 89{
899834b5 90 uint32_t hash[N_HASHES];
652ae149
JA
91 int i, was_set;
92
899834b5 93 for (i = 0; i < N_HASHES; i++) {
7790f697 94 hash[i] = hashes[i].fn(data, len, hashes[i].seed);
899834b5
JA
95 hash[i] = hash[i] % b->nentries;
96 }
652ae149
JA
97
98 was_set = 0;
99 for (i = 0; i < N_HASHES; i++) {
899834b5
JA
100 const unsigned int index = hash[i] / BITS_PER_INDEX;
101 const unsigned int bit = hash[i] & BITS_INDEX_MASK;
652ae149
JA
102
103 if (b->map[index] & (1U << bit))
104 was_set++;
33a908a5 105 else if (set)
652ae149 106 b->map[index] |= 1U << bit;
33a908a5
JA
107 else
108 break;
652ae149
JA
109 }
110
111 return was_set == N_HASHES;
112}
113
c0d75983 114bool bloom_set(struct bloom *b, uint32_t *data, unsigned int nwords)
652ae149 115{
7790f697 116 return __bloom_check(b, data, nwords * sizeof(uint32_t), true);
652ae149 117}
0a301e93 118
eb50727a
JA
119bool bloom_string(struct bloom *b, const char *data, unsigned int len,
120 bool set)
0a301e93 121{
eb50727a 122 return __bloom_check(b, data, len, set);
0a301e93 123}