pub fn enter_joint(
        &mut self,
        auto_leave: bool,
        ccs: &mut [ConfChangeSingle],
    ) -> Result<(Config, ProgressMap), String> {
        check_invariants(&self.tracker.config, &self.tracker.progress)?;
        let mut cfg = self.tracker.config.clone();
        let mut prs = self.tracker.progress.clone();
        info!("enter joint, auto_leave={}, cfg: {}", auto_leave, cfg);
        // prs.extend(self.tracker.progress.clone());
        if cfg.voters.joint() {
            return Err("config is already joint".to_string());
        }

        if cfg.voters.incoming.is_empty() {
            // we allow adding nodes to an empty config for convenience (testing and
            // bootstrap), but you can't enter a joint state.
            return Err("can't make a zero-voter config joint".to_string());
        }
        // clear the outgoing config.
        cfg.voters.outgoing.clear();
        // copy incoming to outgoing
        cfg.voters.outgoing.extend(&cfg.voters.incoming);
        self.apply(&mut cfg, &mut prs, ccs)?;
        cfg.auto_leave = auto_leave;
        Ok((cfg, prs))
    }
/// verifies that the outgoing (=right) majority config of the joint
/// config is empty and initializes it with a copy of the incoming (=left)
/// majority config. That is, it transactions from
/// ```text
///          (1 2 3) && ()
/// ```
/// to
/// ``` text
///          (1 2 3) && (1 2 3)
/// ```.
/// The supplied changes are then applied to the incoming majority config,
/// resulting in a joint configuration that in terms of the Raft thesis[1]
/// (Section 4.3) corresponds to `c_{new, old}`.
///
/// [1]: https://github.com/ongardie/dissertation/blob/master/online-trim.pdf
verifies that the outgoing (=right) majority config of the joint
config is empty and initializes it with a copy of the incoming (=left)
majority config.


verifies that the outgoing ( = right ) majority config of the joint config is empty and initializes it with a copy of the incoming ( = left ) majority config .
pub fn enter_joint(
        &mut self,
        auto_leave: bool,
        ccs: &mut [ConfChangeSingle],
    ) -> Result<(Config, ProgressMap), String> {
        check_invariants(&self.tracker.config, &self.tracker.progress)?;
        let mut cfg = self.tracker.config.clone();
        let mut prs = self.tracker.progress.clone();
        info!("enter joint, auto_leave={}, cfg: {}", auto_leave, cfg);
        // prs.extend(self.tracker.progress.clone());
        if cfg.voters.joint() {
            return Err("config is already joint".to_string());
        }
        if cfg.voters.incoming.is_empty() {
            // we allow adding nodes to an empty config for convenience (testing and
            // bootstrap), but you can't enter a joint state.
            return Err("can't make a zero-voter config joint".to_string());
        }
        // clear the outgoing config.
        cfg.voters.outgoing.clear();
        // copy incoming to outgoing
        cfg.voters.outgoing.extend(&cfg.voters.incoming);
        self.apply(&mut cfg, &mut prs, ccs)?;
        cfg.auto_leave = auto_leave;
        Ok((cfg, prs))
    }
pub fn enter_joint ( & mut self , auto_leave : bool , ccs : & mut [ ConfChangeSingle ] , ) -> Result < ( Config , ProgressMap ) , String > { check_invariants ( & self . tracker . config , & self . tracker . progress ) ? ; let mut cfg = self . tracker . config . clone ( ) ; let mut prs = self . tracker . progress . clone ( ) ; info ! ( " " auto_leave cfg ) ; // prs.extend(self.tracker.progress.clone()); if cfg . voters . joint ( ) { return Err ( " " . to_string ( ) ) ; } if cfg . voters . incoming . is_empty ( ) { // we allow adding nodes to an empty config for convenience (testing and // bootstrap), but you can't enter a joint state. return Err ( " " . to_string ( ) ) ; } // clear the outgoing config. cfg . voters . outgoing . clear ( ) ; // copy incoming to outgoing cfg . voters . outgoing . extend ( & cfg . voters . incoming ) ; self . apply ( & mut cfg , & mut prs , ccs ) ? ; cfg . auto_leave = auto_leave ; Ok ( ( cfg , prs ) ) }
verifies that the outgoing (=right) majority config of the joint
config is empty and initializes it with a copy of the incoming (=left)
majority config.
verifies that the outgoing ( = right ) majority config of the joint config is empty and initializes it with a copy of the incoming ( = left ) majority config .
&mut self
auto_leave
bool
ccs
&mut [ConfChangeSingle]