@@ -35,7 +35,7 @@ pub struct DisjointSet<T> {
35
35
nodes : Vec < RwLock < Node > > ,
36
36
}
37
37
38
- #[ derive( Copy ) ]
38
+ #[ derive( Clone , Copy ) ]
39
39
struct Node {
40
40
rank : usize ,
41
41
parent_idx : usize ,
@@ -44,20 +44,6 @@ struct Node {
44
44
next : usize ,
45
45
}
46
46
47
- // The derived Clone impl doesn't override clone_from,
48
- // so we'll do that here.
49
- impl Clone for Node {
50
- fn clone ( & self ) -> Self {
51
- * self
52
- }
53
-
54
- fn clone_from ( & mut self , source : & Self ) {
55
- self . rank = source. rank ;
56
- self . parent_idx = source. parent_idx ;
57
- self . next = source. next ;
58
- }
59
- }
60
-
61
47
impl < T > DisjointSet < T > {
62
48
/// Creates an empty `DisjointSet`.
63
49
pub fn new ( ) -> Self {
@@ -273,27 +259,18 @@ impl<T> DisjointSet<T> {
273
259
self . find_root_idx ( elem_y_idx) ?,
274
260
) ;
275
261
276
- // We don't have to do anything if this is the case. If we
277
- // didn't check this, we'd cause UB below by attempting
278
- // two mutable borrows of the same element.
279
- if x_root_idx == y_root_idx {
280
- return Some ( false ) ;
281
- }
282
-
283
- let x_root: * mut _ = & mut self . nodes [ x_root_idx] ;
284
- let y_root: * mut _ = & mut self . nodes [ y_root_idx] ;
285
-
286
- // We could just use RwLock::write here and avoid the need
287
- // for unsafe, but since we're in a &mut self context,
288
- // we can just ignore RwLock's overhead.
289
- let ( mut x_root, mut y_root) =
290
- unsafe { ( ( & mut * x_root) . get_mut ( ) , ( & mut * y_root) . get_mut ( ) ) } ;
262
+ let [ x_root, y_root] = match self . nodes . get_disjoint_mut ( [ x_root_idx, y_root_idx] ) {
263
+ Ok ( r) => r,
264
+ // An error here means that both indexes were the same so the elements
265
+ // were already in the same subset, so we don't need to do anything.
266
+ Err ( _) => return Some ( false ) ,
267
+ } ;
268
+ let ( x_root, y_root) = ( x_root. get_mut ( ) , y_root. get_mut ( ) ) ;
291
269
292
270
if x_root. rank < y_root. rank {
293
- // Must use mem::swap here. If we shadowed,
294
- // it'd go out of scope when the if block ended.
271
+ // Now we swap to ensure that x_root is always the one with the higher rank.
295
272
mem:: swap ( & mut x_root_idx, & mut y_root_idx) ;
296
- mem:: swap ( & mut x_root, & mut y_root) ;
273
+ mem:: swap ( x_root, y_root) ;
297
274
}
298
275
299
276
// Now x_root.rank >= y_root.rank no matter what.
@@ -321,7 +298,7 @@ impl<T> DisjointSet<T> {
321
298
/// operation was performed, Some(false) if it didn't need to be,
322
299
/// or None if the element doesn't exist.
323
300
pub fn make_singleton ( & mut self , elem_idx : usize ) -> Option < bool > {
324
- if self . is_singleton ( elem_idx) . contains ( & true ) {
301
+ if self . is_singleton ( elem_idx) ? {
325
302
return Some ( false ) ;
326
303
}
327
304
@@ -330,11 +307,11 @@ impl<T> DisjointSet<T> {
330
307
let ( & next_idx, & prev_idx) = set_idxs. get ( 1 ) . zip ( set_idxs. last ( ) ) . unwrap ( ) ;
331
308
332
309
if prev_idx != elem_idx {
333
- let mut prev = self . nodes [ prev_idx] . get_mut ( ) ;
310
+ let prev = self . nodes [ prev_idx] . get_mut ( ) ;
334
311
prev. next = next_idx;
335
312
}
336
313
337
- let mut node = self . nodes [ elem_idx] . get_mut ( ) ;
314
+ let node = self . nodes [ elem_idx] . get_mut ( ) ;
338
315
339
316
self . roots . insert ( elem_idx) ;
340
317
node. parent_idx = elem_idx;
@@ -427,23 +404,16 @@ impl<T: Eq + Clone> Clone for DisjointSet<T> {
427
404
self . elems . clone_from ( & source. elems ) ;
428
405
429
406
self . nodes . resize_with ( source. num_elements ( ) , || {
430
- // Temporary sentinel value. Node::clone_from should prevent
431
- // this from being an unncessary allocation since it'll be
432
- // only be mutated, not completely overwritten.
407
+ // Temporary sentinel value.
433
408
RwLock :: new ( Node {
434
409
rank : 0 ,
435
410
parent_idx : 0 ,
436
411
next : 0 ,
437
412
} )
438
413
} ) ;
439
414
440
- for ( source_node, dest_node) in source
441
- . nodes
442
- . iter ( )
443
- . map ( |node_rwlock| node_rwlock. read ( ) )
444
- . zip ( self . nodes . iter_mut ( ) )
445
- {
446
- dest_node. get_mut ( ) . clone_from ( & source_node) ;
415
+ for ( source_node, dest_node) in source. nodes . iter ( ) . zip ( self . nodes . iter_mut ( ) ) {
416
+ dest_node. get_mut ( ) . clone_from ( & source_node. read ( ) ) ;
447
417
}
448
418
}
449
419
}
0 commit comments