-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfilter.v
More file actions
90 lines (84 loc) · 1.57 KB
/
Copy pathfilter.v
File metadata and controls
90 lines (84 loc) · 1.57 KB
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
module leveldb
const bloom_filter_name = 'leveldb.BuiltinBloomFilter2'
fn bloom_hash(data []u8) u32 {
seed := u32(0xbc9f1d34)
m := u32(0xc6a4a793)
mut h := seed ^ (u32(data.len) * m)
mut i := 0
for i + 4 <= data.len {
h += read_u32_le(data, i)
h *= m
h ^= h >> 16
i += 4
}
rest := data.len - i
if rest >= 3 {
h += u32(data[i + 2]) << 16
}
if rest >= 2 {
h += u32(data[i + 1]) << 8
}
if rest >= 1 {
h += u32(data[i])
h *= m
h ^= h >> 24
}
return h
}
struct BloomFilter {
bits_per_key int
k int
}
fn new_bloom_filter(bits_per_key int) &BloomFilter {
mut k := int(f64(bits_per_key) * 0.69)
if k < 1 {
k = 1
}
if k > 30 {
k = 30
}
return &BloomFilter{
bits_per_key: bits_per_key
k: k
}
}
fn (bf &BloomFilter) create(keys [][]u8) []u8 {
mut bits := keys.len * bf.bits_per_key
if bits < 64 {
bits = 64
}
bytes := (bits + 7) / 8
bits = bytes * 8
mut filter := []u8{len: bytes + 1}
filter[bytes] = u8(bf.k)
for key in keys {
mut h := bloom_hash(key)
delta := (h >> 17) | (h << 15)
for _ in 0 .. bf.k {
bit_pos := h % u32(bits)
filter[bit_pos / 8] |= u8(1) << (bit_pos % 8)
h += delta
}
}
return filter
}
fn (bf &BloomFilter) may_contain(filter []u8, key []u8) bool {
if filter.len < 2 {
return false
}
bits := u32((filter.len - 1) * 8)
k := filter[filter.len - 1]
if k > 30 {
return true
}
mut h := bloom_hash(key)
delta := (h >> 17) | (h << 15)
for _ in 0 .. k {
bit_pos := h % bits
if filter[bit_pos / 8] & (u8(1) << (bit_pos % 8)) == 0 {
return false
}
h += delta
}
return true
}