Merge pull request #278 from petgraph/unionfind-perf
Improve performance of UnionFind's find_mut
diff --git a/src/unionfind.rs b/src/unionfind.rs
index bbc9a06..986d60d 100644
--- a/src/unionfind.rs
+++ b/src/unionfind.rs
@@ -33,6 +33,13 @@
xs.get_unchecked(index)
}
+#[inline]
+unsafe fn get_unchecked_mut<K>(xs: &mut [K], index: usize) -> &mut K
+{
+ debug_assert!(index < xs.len());
+ xs.get_unchecked_mut(index)
+}
+
impl<K> UnionFind<K>
where K: IndexType
{
@@ -79,17 +86,16 @@
}
}
- unsafe fn find_mut_recursive(&mut self, x: K) -> K
+ unsafe fn find_mut_recursive(&mut self, mut x: K) -> K
{
- let xparent = *get_unchecked(&self.parent, x.index());
- if xparent != x {
- let xrep = self.find_mut_recursive(xparent);
- let xparent = self.parent.get_unchecked_mut(x.index());
- *xparent = xrep;
- *xparent
- } else {
- xparent
+ let mut parent = *get_unchecked(&self.parent, x.index());
+ while parent != x {
+ let grandparent = *get_unchecked(&self.parent, parent.index());
+ *get_unchecked_mut(&mut self.parent, x.index()) = grandparent;
+ x = parent;
+ parent = grandparent;
}
+ x
}
/// Returns `true` if the given elements belong to the same set, and returns