/// Unions two eclasses given their ids.
///
/// The given ids need not be canonical.
/// The returned `bool` indicates whether a union was done,
/// so it's `false` if they were already equivalent.
/// Both results are canonical.
Unions two eclasses given their ids.
The given ids need not be canonical.
The returned `bool` indicates whether a union was done,
so it's `false` if they were already equivalent.
Both results are canonical.
Unions two eclasses given their ids . The given ids need not be canonical . The returned ` bool ` indicates whether a union was done so it ' s ` false ` if they were already equivalent . Both results are canonical .
pub fn union(&mut self, mut id1: Id, mut id2: Id) -> (Id, bool) {
        id1 = self.find_mut(id1);
        id2 = self.find_mut(id2);
        if id1 == id2 {
            return (id1, false);
        }
        // make sure class2 has fewer parents
        let class1_parents = self.classes[&id1].parents.len();
        let class2_parents = self.classes[&id2].parents.len();
        if class1_parents < class2_parents {
            std::mem::swap(&mut id1, &mut id2);
        }
        N::pre_union(self, id1, id2);
        // make id1 the new root
        self.unionfind.union(id1, id2);
        assert_ne!(id1, id2);
        let class2 = self.classes.remove(&id2).unwrap();
        let class1 = self.classes.get_mut(&id1).unwrap();
        assert_eq!(id1, class1.id);
        self.pending.extend(class2.parents.iter().cloned());
        match self.analysis.merge(&mut class1.data, class2.data) {
            Some(Ordering::Equal) => {}
            Some(Ordering::Greater) => {
                self.analysis_pending.extend(class2.parents.iter().cloned());
            }
            Some(Ordering::Less) => {
                self.analysis_pending.extend(class1.parents.iter().cloned());
            }
            None => {
                let both = class1.parents.iter().chain(&class2.parents).cloned();
                self.analysis_pending.extend(both);
            }
        }
        concat_vecs(&mut class1.nodes, class2.nodes);
        concat_vecs(&mut class1.parents, class2.parents);
        N::modify(self, id1);
        (id1, id1 != id2)
    }
pub fn union ( & mut self , mut id1 : Id , mut id2 : Id ) -> ( Id , bool ) { id1 = self . find_mut ( id1 ) ; id2 = self . find_mut ( id2 ) ; if id1 == id2 { return ( id1 , false ) ; } // make sure class2 has fewer parents let class1_parents = self . classes [ & id1 ] . parents . len ( ) ; let class2_parents = self . classes [ & id2 ] . parents . len ( ) ; if class1_parents < class2_parents { std :: mem :: swap ( & mut id1 , & mut id2 ) ; } N :: pre_union ( self , id1 , id2 ) ; // make id1 the new root self . unionfind . union ( id1 , id2 ) ; assert_ne ! ( id1 id2 ) ; let class2 = self . classes . remove ( & id2 ) . unwrap ( ) ; let class1 = self . classes . get_mut ( & id1 ) . unwrap ( ) ; assert_eq ! ( id1 class1 id ) ; self . pending . extend ( class2 . parents . iter ( ) . cloned ( ) ) ; match self . analysis . merge ( & mut class1 . data , class2 . data ) { Some ( Ordering :: Equal ) => { } Some ( Ordering :: Greater ) => { self . analysis_pending . extend ( class2 . parents . iter ( ) . cloned ( ) ) ; } Some ( Ordering :: Less ) => { self . analysis_pending . extend ( class1 . parents . iter ( ) . cloned ( ) ) ; } None => { let both = class1 . parents . iter ( ) . chain ( & class2 . parents ) . cloned ( ) ; self . analysis_pending . extend ( both ) ; } } concat_vecs ( & mut class1 . nodes , class2 . nodes ) ; concat_vecs ( & mut class1 . parents , class2 . parents ) ; N :: modify ( self , id1 ) ; ( id1 , id1 != id2 ) }
Unions two eclasses given their ids.
Unions two eclasses given their ids .
&mut self
id1
Id
id2
Id