-
Notifications
You must be signed in to change notification settings - Fork 669
/
read_filter.go
65 lines (56 loc) · 1.49 KB
/
read_filter.go
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
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package bloom
import (
"encoding/binary"
"fmt"
)
var (
EmptyFilter = &ReadFilter{
hashSeeds: make([]uint64, minHashes),
entries: make([]byte, minEntries),
}
FullFilter = &ReadFilter{
hashSeeds: make([]uint64, minHashes),
entries: make([]byte, minEntries),
}
)
func init() {
for i := range FullFilter.entries {
FullFilter.entries[i] = 0xFF
}
}
type ReadFilter struct {
hashSeeds []uint64
entries []byte
}
// Parse [bytes] into a read-only bloom filter.
func Parse(bytes []byte) (*ReadFilter, error) {
if len(bytes) == 0 {
return nil, errInvalidNumHashes
}
numHashes := bytes[0]
entriesOffset := 1 + int(numHashes)*bytesPerUint64
switch {
case numHashes < minHashes:
return nil, fmt.Errorf("%w: %d < %d", errTooFewHashes, numHashes, minHashes)
case numHashes > maxHashes:
return nil, fmt.Errorf("%w: %d > %d", errTooManyHashes, numHashes, maxHashes)
case len(bytes) < entriesOffset+minEntries: // numEntries = len(bytes) - entriesOffset
return nil, errTooFewEntries
}
f := &ReadFilter{
hashSeeds: make([]uint64, numHashes),
entries: bytes[entriesOffset:],
}
for i := range f.hashSeeds {
f.hashSeeds[i] = binary.BigEndian.Uint64(bytes[1+i*bytesPerUint64:])
}
return f, nil
}
func (f *ReadFilter) Contains(hash uint64) bool {
return contains(f.hashSeeds, f.entries, hash)
}
func (f *ReadFilter) Marshal() []byte {
return marshal(f.hashSeeds, f.entries)
}