1
- use std:: hash:: BuildHasher ;
2
- use std:: hash:: Hash ;
3
- use std:: hash:: Hasher ;
4
- use std:: sync:: Arc ;
5
-
6
- use crate :: xor8:: filter:: fingerprint;
7
- use crate :: xor8:: filter:: splitmix64;
8
- use crate :: xor8:: filter:: XorSet ;
9
- use crate :: xor8:: Xor8 ;
10
- use crate :: BuildHasherDefault ;
1
+ use std:: {
2
+ hash:: { BuildHasher , Hash , Hasher } ,
3
+ sync:: Arc ,
4
+ } ;
5
+
6
+ use crate :: {
7
+ xor8:: {
8
+ filter:: { fingerprint, splitmix64, XorSet } ,
9
+ Xor8 ,
10
+ } ,
11
+ BuildHasherDefault ,
12
+ } ;
11
13
12
14
#[ derive( Clone , Copy , Default ) ]
13
15
struct KeyIndex {
@@ -56,15 +58,17 @@ type U64HashSet = ::std::collections::HashSet<u64, U64IdentifyBuildHasher>;
56
58
/// ```
57
59
#[ derive( Clone , Debug ) ]
58
60
pub struct Xor8Builder < H = BuildHasherDefault >
59
- where H : BuildHasher + Clone
61
+ where
62
+ H : BuildHasher + Clone ,
60
63
{
61
64
digests : U64HashSet ,
62
65
pub num_digests : usize ,
63
66
pub hash_builder : H ,
64
67
}
65
68
66
69
impl < H > Default for Xor8Builder < H >
67
- where H : BuildHasher + Clone + Default
70
+ where
71
+ H : BuildHasher + Clone + Default ,
68
72
{
69
73
fn default ( ) -> Self {
70
74
Self {
@@ -76,11 +80,14 @@ where H: BuildHasher + Clone + Default
76
80
}
77
81
78
82
impl < H > Xor8Builder < H >
79
- where H : BuildHasher + Clone
83
+ where
84
+ H : BuildHasher + Clone ,
80
85
{
81
86
/// New Xor8 builder initialized with [BuildHasherDefault].
82
87
pub fn new ( ) -> Self
83
- where H : Default {
88
+ where
89
+ H : Default ,
90
+ {
84
91
Self :: default ( )
85
92
}
86
93
@@ -107,8 +114,8 @@ where H: BuildHasher + Clone
107
114
108
115
/// Insert 64-bit digest of a single key.
109
116
///
110
- /// Digest for the key shall be generated using the default-hasher or via hasher
111
- /// supplied via [Xor8Builder::with_hasher] method.
117
+ /// Digest for the key shall be generated using the default-hasher or via
118
+ /// hasher supplied via [Xor8Builder::with_hasher] method.
112
119
pub fn insert < K : ?Sized + Hash > ( & mut self , key : & K ) {
113
120
let digest = self . hash ( key) ;
114
121
@@ -118,8 +125,8 @@ where H: BuildHasher + Clone
118
125
119
126
/// Populate with 64-bit digests for a collection of keys of type `K`.
120
127
///
121
- /// Digest for key shall be generated using the default-hasher or via hasher supplied
122
- /// via [Xor8Builder::with_hasher] method.
128
+ /// Digest for key shall be generated using the default-hasher or via hasher
129
+ /// supplied via [Xor8Builder::with_hasher] method.
123
130
pub fn populate < ' i , K : Hash + ' i , I : IntoIterator < Item = & ' i K > > ( & mut self , keys : I ) {
124
131
let mut n = 0 ;
125
132
@@ -145,28 +152,49 @@ where H: BuildHasher + Clone
145
152
self . num_digests += n;
146
153
}
147
154
148
- /// Build bitmap for keys that where previously inserted using [Xor8Builder::insert],
149
- /// [Xor8Builder::populate] and [Xor8Builder::populate_digests] method.
155
+ /// Build bitmap for keys that where previously inserted using
156
+ /// [Xor8Builder::insert], [Xor8Builder::populate] and
157
+ /// [Xor8Builder::populate_digests] method.
150
158
pub fn build ( & mut self ) -> Result < Xor8 < H > , crate :: Error > {
151
- let digests = self . digests . iter ( ) . copied ( ) . collect :: < Vec < u64 > > ( ) ;
152
- self . build_from_digests ( & digests)
159
+ let digest_len = self . digests . len ( ) ;
160
+ Self :: build_inner (
161
+ self . hash_builder . clone ( ) ,
162
+ self . digests . iter ( ) . copied ( ) ,
163
+ digest_len,
164
+ )
153
165
}
154
166
155
167
/// Build a bitmap for pre-computed 64-bit digests for keys.
156
168
///
157
169
/// If keys where previously inserted using [Xor8Builder::insert] or
158
- /// [Xor8Builder::populate] or [Xor8Builder::populate_digests] methods, they shall be
159
- /// ignored.
170
+ /// [Xor8Builder::populate] or [Xor8Builder::populate_digests] methods, they
171
+ /// shall be ignored.
160
172
///
161
- /// It is upto the caller to ensure that digests are unique, that there no duplicates.
173
+ /// It is upto the caller to ensure that digests are unique, that there no
174
+ /// duplicates.
162
175
pub fn build_from_digests (
163
176
& mut self ,
164
177
digests : & [ u64 ] ,
165
178
) -> Result < Xor8 < H > , crate :: Error > {
166
- let mut ff = Xor8 :: < H > :: new ( self . hash_builder . clone ( ) ) ;
179
+ Self :: build_inner (
180
+ self . hash_builder . clone ( ) ,
181
+ digests. iter ( ) . copied ( ) ,
182
+ digests. len ( ) ,
183
+ )
184
+ }
167
185
168
- ff. num_keys = Some ( digests. len ( ) ) ;
169
- let ( size, mut rngcounter) = ( digests. len ( ) , 1_u64 ) ;
186
+ fn build_inner < It > (
187
+ hash_builder : H ,
188
+ digest_iter : It ,
189
+ digest_len : usize ,
190
+ ) -> Result < Xor8 < H > , crate :: Error >
191
+ where
192
+ It : Iterator < Item = u64 > + Clone ,
193
+ {
194
+ let mut ff = Xor8 :: < H > :: new ( hash_builder) ;
195
+
196
+ ff. num_keys = Some ( digest_len) ;
197
+ let ( size, mut rngcounter) = ( digest_len, 1_u64 ) ;
170
198
let capacity = {
171
199
let capacity = 32 + ( ( 1.23 * ( size as f64 ) ) . ceil ( ) as u32 ) ;
172
200
capacity / 3 * 3 // round it down to a multiple of 3
@@ -185,8 +213,8 @@ where H: BuildHasher + Clone
185
213
let mut sets2: Vec < XorSet > = vec ! [ XorSet :: default ( ) ; block_length] ;
186
214
187
215
loop {
188
- for key in digests . iter ( ) {
189
- let hs = ff. get_h0h1h2 ( * key) ;
216
+ for key in digest_iter . clone ( ) {
217
+ let hs = ff. get_h0h1h2 ( key) ;
190
218
sets0[ hs. h0 as usize ] . xor_mask ^= hs. h ;
191
219
sets0[ hs. h0 as usize ] . count += 1 ;
192
220
sets1[ hs. h1 as usize ] . xor_mask ^= hs. h ;
0 commit comments