@@ -10,7 +10,7 @@ use crate::parameter_cache::ParameterSetIdentifier;
10
10
11
11
pub const DEFAULT_EXPANSION_DEGREE : usize = 8 ;
12
12
13
- #[ derive( Debug , Clone , Eq , PartialEq ) ]
13
+ #[ derive( Debug ) ]
14
14
pub struct ZigZagGraph < H , G >
15
15
where
16
16
H : Hasher ,
@@ -87,7 +87,7 @@ pub trait ZigZag: ::std::fmt::Debug + Clone + PartialEq + Eq {
87
87
fn reversed ( & self ) -> bool ;
88
88
fn expanded_parents ( & self , node : usize ) -> Vec < usize > ;
89
89
fn real_index ( & self , i : usize ) -> usize ;
90
- fn parents_cache ( & self ) -> RwLock < HashMap < usize , Vec < usize > > > ;
90
+ fn parents_cache ( & self ) -> & RwLock < HashMap < usize , Vec < usize > > > ;
91
91
fn new_zigzag (
92
92
nodes : usize ,
93
93
base_degree : usize ,
@@ -155,6 +155,7 @@ impl<Z: ZigZag> Graph<Z::BaseHasher> for Z {
155
155
fn forward ( & self ) -> bool {
156
156
!self . reversed ( )
157
157
}
158
+
158
159
}
159
160
160
161
impl < ' a , H , G > ZigZagGraph < H , G >
@@ -183,6 +184,7 @@ where
183
184
} ;
184
185
transformed as usize / self . expansion_degree
185
186
}
187
+
186
188
}
187
189
188
190
impl < ' a , H , G > ZigZag for ZigZagGraph < H , G >
@@ -230,10 +232,16 @@ where
230
232
#[ inline]
231
233
fn expanded_parents ( & self , node : usize ) -> Vec < usize > {
232
234
233
- // let parents_cache = self.parents_cache().read().unwrap();
234
- // if (*parents_cache).contains_key(&node) {
235
- // return (*parents_cache)[&node].clone();
236
- // }
235
+ {
236
+ let parents_cache = self . parents_cache ( ) . read ( ) . unwrap ( ) ;
237
+ if ( * parents_cache) . contains_key ( & node) {
238
+ return ( * parents_cache) [ & node] . clone ( ) ;
239
+ // TODO(dig): We should change the signature to return a &[]u8 instead,
240
+ // cloning vectors is expensive, and reduces teh usefullness of the cache.
241
+ }
242
+ // Release the read lock (a write one will be taken later).
243
+ // TODO: Is this necessary? Can we keep a single write lock across the entire function?
244
+ }
237
245
238
246
let parents: Vec < usize > = ( 0 ..self . expansion_degree )
239
247
. filter_map ( |i| {
@@ -252,8 +260,8 @@ where
252
260
} )
253
261
. collect ( ) ;
254
262
255
- // let mut parents_cache = self.parents_cache().write().unwrap();
256
- // (*parents_cache).insert(node, parents.clone());
263
+ let mut parents_cache = self . parents_cache ( ) . write ( ) . unwrap ( ) ;
264
+ ( * parents_cache) . insert ( node, parents. clone ( ) ) ;
257
265
258
266
parents
259
267
}
@@ -267,11 +275,46 @@ where
267
275
}
268
276
}
269
277
270
- fn parents_cache ( & self ) -> RwLock < HashMap < usize , Vec < usize > > > {
271
- self . parents_cache
278
+ fn parents_cache ( & self ) -> & RwLock < HashMap < usize , Vec < usize > > > {
279
+ & self . parents_cache
280
+ }
281
+ }
282
+
283
+ impl < H , G > Clone for ZigZagGraph < H , G >
284
+ where
285
+ H : Hasher ,
286
+ G : Graph < H > ,
287
+ {
288
+ fn clone ( & self ) -> ZigZagGraph < H , G > {
289
+ ZigZagGraph {
290
+ base_graph : self . base_graph . clone ( ) ,
291
+ expansion_degree : self . expansion_degree ,
292
+ reversed : self . reversed ,
293
+ feistel_precomputed : feistel:: precompute ( ( self . expansion_degree * self . size ( ) ) as u32 ) ,
294
+ parents_cache : RwLock :: new ( HashMap :: new ( ) ) ,
295
+ _h : PhantomData ,
296
+ }
297
+ }
298
+ }
299
+
300
+ impl < H , G > PartialEq for ZigZagGraph < H , G >
301
+ where
302
+ H : Hasher ,
303
+ G : Graph < H > ,
304
+ {
305
+ fn eq ( & self , other : & ZigZagGraph < H , G > ) -> bool {
306
+ self . base_graph == other. base_graph &&
307
+ self . expansion_degree == other. expansion_degree &&
308
+ self . reversed == other. reversed
272
309
}
273
310
}
274
311
312
+ impl < H , G > Eq for ZigZagGraph < H , G >
313
+ where
314
+ H : Hasher ,
315
+ G : Graph < H > ,
316
+ { }
317
+
275
318
#[ cfg( test) ]
276
319
mod tests {
277
320
use super :: * ;
0 commit comments