crc/test: add jhash
[fio.git] / lib / bloom.c
CommitLineData
652ae149
JA
1#include <stdlib.h>
2#include <inttypes.h>
3
4#include "bloom.h"
5#include "../hash.h"
265c0032 6#include "../minmax.h"
899834b5 7#include "../crc/xxhash.h"
9f0e365d 8#include "../lib/murmur3.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
899834b5
JA
24struct bloom_hash hashes[] = {
25 {
26 .seed = 0x8989,
27 .fn = jhash,
28 },
29 {
30 .seed = 0x8989,
31 .fn = XXH32,
32 },
33 {
9f0e365d
JA
34 .seed = 0x8989,
35 .fn = murmurhash3,
899834b5
JA
36 },
37};
38
652ae149
JA
39#define N_HASHES 3
40
265c0032
JA
41#define MIN_ENTRIES 1073741824UL
42
652ae149
JA
43struct bloom *bloom_new(uint64_t entries)
44{
45 struct bloom *b;
46 size_t no_uints;
47
48 b = malloc(sizeof(*b));
49 b->nentries = entries;
50 no_uints = (entries + BITS_PER_INDEX - 1) / BITS_PER_INDEX;
265c0032 51 no_uints = max((unsigned long) no_uints, MIN_ENTRIES);
652ae149
JA
52 b->map = calloc(no_uints, sizeof(uint32_t));
53 if (!b->map) {
54 free(b);
55 return NULL;
56 }
57
58 return b;
59}
60
61void bloom_free(struct bloom *b)
62{
63 free(b->map);
64 free(b);
65}
66
67static int __bloom_check(struct bloom *b, uint32_t *data, unsigned int nwords,
68 int set)
69{
899834b5 70 uint32_t hash[N_HASHES];
652ae149
JA
71 int i, was_set;
72
899834b5
JA
73 for (i = 0; i < N_HASHES; i++) {
74 hash[i] = hashes[i].fn(data, nwords, hashes[i].seed);
75 hash[i] = hash[i] % b->nentries;
76 }
652ae149
JA
77
78 was_set = 0;
79 for (i = 0; i < N_HASHES; i++) {
899834b5
JA
80 const unsigned int index = hash[i] / BITS_PER_INDEX;
81 const unsigned int bit = hash[i] & BITS_INDEX_MASK;
652ae149
JA
82
83 if (b->map[index] & (1U << bit))
84 was_set++;
85 if (set)
86 b->map[index] |= 1U << bit;
87 }
88
89 return was_set == N_HASHES;
90}
91
92int bloom_check(struct bloom *b, uint32_t *data, unsigned int nwords)
93{
94 return __bloom_check(b, data, nwords, 0);
95}
96
97int bloom_set(struct bloom *b, uint32_t *data, unsigned int nwords)
98{
99 return __bloom_check(b, data, nwords, 1);
100}