1
- use super :: bit_array:: BitArrayReader ;
1
+ use super :: { bit_array:: BitArrayReader , AMQFilter } ;
2
2
use crate :: {
3
3
coding:: { Decode , DecodeError , Encode , EncodeError } ,
4
4
file:: MAGIC_BYTES ,
@@ -30,6 +30,49 @@ pub struct StandardBloomFilter {
30
30
}
31
31
32
32
// TODO: change encode/decode to be Filter enum
33
+ impl AMQFilter for StandardBloomFilter {
34
+ /// Size of bloom filter in bytes.
35
+ #[ must_use]
36
+ fn len ( & self ) -> usize {
37
+ self . inner . bytes ( ) . len ( )
38
+ }
39
+
40
+ /// Returns the raw bytes of the filter.
41
+ fn bytes ( & self ) -> & [ u8 ] {
42
+ self . inner . bytes ( )
43
+ }
44
+
45
+ /// Returns `true` if the item may be contained.
46
+ ///
47
+ /// Will never have a false negative.
48
+ #[ must_use]
49
+ fn contains ( & self , key : & [ u8 ] ) -> bool {
50
+ self . contains_hash ( Self :: get_hash ( key) )
51
+ }
52
+
53
+ /// Returns `true` if the hash may be contained.
54
+ ///
55
+ /// Will never have a false negative.
56
+ #[ must_use]
57
+ fn contains_hash ( & self , hash : CompositeHash ) -> bool {
58
+ let ( mut h1, mut h2) = hash;
59
+
60
+ for i in 1 ..=( self . k as u64 ) {
61
+ let idx = h1 % ( self . m as u64 ) ;
62
+
63
+ // NOTE: should be in bounds because of modulo
64
+ #[ allow( clippy:: expect_used) ]
65
+ if !self . has_bit ( idx as usize ) {
66
+ return false ;
67
+ }
68
+
69
+ h1 = h1. wrapping_add ( h2) ;
70
+ h2 = h2. wrapping_mul ( i) ;
71
+ }
72
+
73
+ true
74
+ }
75
+ }
33
76
34
77
impl Encode for StandardBloomFilter {
35
78
fn encode_into < W : Write > ( & self , writer : & mut W ) -> Result < ( ) , EncodeError > {
@@ -50,20 +93,10 @@ impl Encode for StandardBloomFilter {
50
93
}
51
94
}
52
95
53
- impl Decode for StandardBloomFilter {
54
- fn decode_from < R : Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
55
- // Check header
56
- let mut magic = [ 0u8 ; MAGIC_BYTES . len ( ) ] ;
57
- reader. read_exact ( & mut magic) ?;
58
-
59
- if magic != MAGIC_BYTES {
60
- return Err ( DecodeError :: InvalidHeader ( "BloomFilter" ) ) ;
61
- }
62
-
63
- // NOTE: Filter type (unused)
64
- let filter_type = reader. read_u8 ( ) ?;
65
- assert_eq ! ( 0 , filter_type, "Invalid filter type" ) ;
66
-
96
+ #[ allow( clippy:: len_without_is_empty) ]
97
+ impl StandardBloomFilter {
98
+ // To be used by AMQFilter after magic bytes and filter type have been read and parsed
99
+ pub ( super ) fn decode_from < R : Read > ( reader : & mut R ) -> Result < Self , DecodeError > {
67
100
// NOTE: Hash type (unused)
68
101
let hash_type = reader. read_u8 ( ) ?;
69
102
assert_eq ! ( 0 , hash_type, "Invalid bloom hash type" ) ;
@@ -76,15 +109,6 @@ impl Decode for StandardBloomFilter {
76
109
77
110
Ok ( Self :: from_raw ( m, k, bytes. into ( ) ) )
78
111
}
79
- }
80
-
81
- #[ allow( clippy:: len_without_is_empty) ]
82
- impl StandardBloomFilter {
83
- /// Size of bloom filter in bytes.
84
- #[ must_use]
85
- pub fn len ( & self ) -> usize {
86
- self . inner . bytes ( ) . len ( )
87
- }
88
112
89
113
fn from_raw ( m : usize , k : usize , slice : crate :: Slice ) -> Self {
90
114
Self {
@@ -94,37 +118,6 @@ impl StandardBloomFilter {
94
118
}
95
119
}
96
120
97
- /// Returns `true` if the hash may be contained.
98
- ///
99
- /// Will never have a false negative.
100
- #[ must_use]
101
- pub fn contains_hash ( & self , hash : CompositeHash ) -> bool {
102
- let ( mut h1, mut h2) = hash;
103
-
104
- for i in 1 ..=( self . k as u64 ) {
105
- let idx = h1 % ( self . m as u64 ) ;
106
-
107
- // NOTE: should be in bounds because of modulo
108
- #[ allow( clippy:: expect_used) ]
109
- if !self . has_bit ( idx as usize ) {
110
- return false ;
111
- }
112
-
113
- h1 = h1. wrapping_add ( h2) ;
114
- h2 = h2. wrapping_mul ( i) ;
115
- }
116
-
117
- true
118
- }
119
-
120
- /// Returns `true` if the item may be contained.
121
- ///
122
- /// Will never have a false negative.
123
- #[ must_use]
124
- pub fn contains ( & self , key : & [ u8 ] ) -> bool {
125
- self . contains_hash ( Self :: get_hash ( key) )
126
- }
127
-
128
121
/// Returns `true` if the bit at `idx` is `1`.
129
122
fn has_bit ( & self , idx : usize ) -> bool {
130
123
self . inner . get ( idx)
@@ -138,6 +131,8 @@ impl StandardBloomFilter {
138
131
139
132
#[ cfg( test) ]
140
133
mod tests {
134
+ use crate :: segment:: filter:: AMQFilterBuilder ;
135
+
141
136
use super :: * ;
142
137
use std:: fs:: File ;
143
138
use test_log:: test;
@@ -174,9 +169,9 @@ mod tests {
174
169
drop ( file) ;
175
170
176
171
let mut file = File :: open ( & path) ?;
177
- let filter_copy = StandardBloomFilter :: decode_from ( & mut file) ?;
172
+ let filter_copy = AMQFilterBuilder :: decode_from ( & mut file) ?;
178
173
179
- assert_eq ! ( filter. inner, filter_copy. inner ) ;
174
+ assert_eq ! ( filter. inner. bytes ( ) , filter_copy. bytes ( ) ) ;
180
175
181
176
for key in keys {
182
177
assert ! ( filter. contains( & * * key) ) ;
0 commit comments