pub(crate) fn restore(&mut self, s: &Snapshot) -> bool {
        if s.get_metadata().get_index() <= self.raft_log.committed {
            return false;
        }

        if self.state != StateType::Follower {
            // This is defense-in-depth: if the leader somehow ended up applying a
            // snapshot, it could move into a new term without moving into a
            // follower state. This should never fire, but if it did, we'd have
            // prevented damage by returning early, so log only a loud warning.
            //
            // At the time of writing, the instance is guaranteed to be in follower
            // state when this method is called.
            warn!(
                "{:x} attempted to restore snapshot as leader; should never happen",
                self.id
            );
            self.become_follower(self.term + 1, NONE);
            return false;
        }

        // More defense-in-depth: throw away snapshot if recipient is not in the
        // config. This shouldn't ever happen (at the time of writing) but lots of
        // code here and there assumes that r.id is in the progress tracker.
        let cs = s.get_metadata().get_conf_state();
        let found = vec![cs.voters.clone(), cs.learners.clone()]
            .iter()
            .flatten()
            .any(|id| *id == self.id);
        if !found {
            warn!(
                "{:#x} attempted to restore snapshot but it is not in the ConfState {:?}; should never happen",
                self.id, cs
            );
            return false;
        }

        // Now go ahead and actually restore.
        if self
            .raft_log
            .match_term(s.get_metadata().get_index(), s.get_metadata().get_term())
        {
            info!(
                "{:#x} [commit: {}, last_index: {}, last_term: {}] fast-forwarded commit to snapshot [index: {}, term: {}]",
                self.id,
                self.raft_log.committed,
                self.raft_log.last_index(),
                self.raft_log.last_term(),
                s.get_metadata().get_index(),
                s.get_metadata().get_term()
            );
            return false;
        }

        // TODO:option
        self.raft_log.restore(s.clone());

        // Reset the configuration and add the (potentially updated) peers in anew.
        self.prs = ProgressTracker::new(self.prs.max_inflight);
        let (cfg, prs) = restore(
            &mut Changer {
                tracker: self.prs.clone(),
                last_index: self.raft_log.last_index(),
            },
            cs,
        )
            // This should never happen. Either there's a bug in our config change
            // handling or the client corrupted the conf change.
            .map_err(|err| panic!("unable to restore config {:?}: {}", cs, err))
            .unwrap();
        equivalent(cs, &self.switch_to_config(cfg, prs)).unwrap();
        let pr = self.prs.progress.get_mut(&self.id).unwrap();
        pr.maybe_update(pr.next - 1); // TODO(tbg): this is untested and likely unneeded

        info!(
            "{:#x} [commit: {}, last_index: {}, last_term: {}] restored snapshot [index: {}, term: {}]",
            self.id,
            self.raft_log.committed,
            self.raft_log.last_index(),
            self.raft_log.last_term(),
            s.get_metadata().get_index(),
            s.get_metadata().get_term()
        );

        true
    }
// recovers the state machine from a snapshot. It restores the log and the
// configuration of state machine. If this method returns false, the snapshot was
// ignored, either because it was obsolete or because of an error.
recovers the state machine from a snapshot. It restores the log and the
configuration of state machine. If this method returns false, the snapshot was
ignored, either because it was obsolete or because of an error.
recovers the state machine from a snapshot . It restores the log and the configuration of state machine . If this method returns false the snapshot was ignored either because it was obsolete or because of an error .
pub(crate) fn restore(&mut self, s: &Snapshot) -> bool {
        if s.get_metadata().get_index() <= self.raft_log.committed {
            return false;
        }
        if self.state != StateType::Follower {
            // This is defense-in-depth: if the leader somehow ended up applying a
            // snapshot, it could move into a new term without moving into a
            // follower state. This should never fire, but if it did, we'd have
            // prevented damage by returning early, so log only a loud warning.
            //
            // At the time of writing, the instance is guaranteed to be in follower
            // state when this method is called.
            warn!(
                "{:x} attempted to restore snapshot as leader; should never happen",
                self.id
            );
            self.become_follower(self.term + 1, NONE);
            return false;
        }
        // More defense-in-depth: throw away snapshot if recipient is not in the
        // config. This shouldn't ever happen (at the time of writing) but lots of
        // code here and there assumes that r.id is in the progress tracker.
        let cs = s.get_metadata().get_conf_state();
        let found = vec![cs.voters.clone(), cs.learners.clone()]
            .iter()
            .flatten()
            .any(|id| *id == self.id);
        if !found {
            warn!(
                "{:#x} attempted to restore snapshot but it is not in the ConfState {:?}; should never happen",
                self.id, cs
            );
            return false;
        }
        // Now go ahead and actually restore.
        if self
            .raft_log
            .match_term(s.get_metadata().get_index(), s.get_metadata().get_term())
        {
            info!(
                "{:#x} [commit: {}, last_index: {}, last_term: {}] fast-forwarded commit to snapshot [index: {}, term: {}]",
                self.id,
                self.raft_log.committed,
                self.raft_log.last_index(),
                self.raft_log.last_term(),
                s.get_metadata().get_index(),
                s.get_metadata().get_term()
            );
            return false;
        }
        // TODO:option
        self.raft_log.restore(s.clone());
        // Reset the configuration and add the (potentially updated) peers in anew.
        self.prs = ProgressTracker::new(self.prs.max_inflight);
        let (cfg, prs) = restore(
            &mut Changer {
                tracker: self.prs.clone(),
                last_index: self.raft_log.last_index(),
            },
            cs,
        )
            // This should never happen. Either there's a bug in our config change
            // handling or the client corrupted the conf change.
            .map_err(|err| panic!("unable to restore config {:?}: {}", cs, err))
            .unwrap();
        equivalent(cs, &self.switch_to_config(cfg, prs)).unwrap();
        let pr = self.prs.progress.get_mut(&self.id).unwrap();
        pr.maybe_update(pr.next - 1); // TODO(tbg): this is untested and likely unneeded
        info!(
            "{:#x} [commit: {}, last_index: {}, last_term: {}] restored snapshot [index: {}, term: {}]",
            self.id,
            self.raft_log.committed,
            self.raft_log.last_index(),
            self.raft_log.last_term(),
            s.get_metadata().get_index(),
            s.get_metadata().get_term()
        );
        true
    }
pub ( crate ) fn restore ( & mut self , s : & Snapshot ) -> bool { if s . get_metadata ( ) . get_index ( ) <= self . raft_log . committed { return false ; } if self . state != StateType :: Follower { // This is defense-in-depth: if the leader somehow ended up applying a // snapshot, it could move into a new term without moving into a // follower state. This should never fire, but if it did, we'd have // prevented damage by returning early, so log only a loud warning. // // At the time of writing, the instance is guaranteed to be in follower // state when this method is called. warn ! ( " " self id ) ; self . become_follower ( self . term + 1 , NONE ) ; return false ; } // More defense-in-depth: throw away snapshot if recipient is not in the // config. This shouldn't ever happen (at the time of writing) but lots of // code here and there assumes that r.id is in the progress tracker. let cs = s . get_metadata ( ) . get_conf_state ( ) ; let found = vec ! [ cs voters clone ( ) cs learners clone ( ) ] . iter ( ) . flatten ( ) . any ( | id | * id == self . id ) ; if ! found { warn ! ( " " self id cs ) ; return false ; } // Now go ahead and actually restore. if self . raft_log . match_term ( s . get_metadata ( ) . get_index ( ) , s . get_metadata ( ) . get_term ( ) ) { info ! ( " " self id self raft_log committed self raft_log last_index ( ) self raft_log last_term ( ) s get_metadata ( ) get_index ( ) s get_metadata ( ) get_term ( ) ) ; return false ; } // TODO:option self . raft_log . restore ( s . clone ( ) ) ; // Reset the configuration and add the (potentially updated) peers in anew. self . prs = ProgressTracker :: new ( self . prs . max_inflight ) ; let ( cfg , prs ) = restore ( & mut Changer { tracker : self . prs . clone ( ) , last_index : self . raft_log . last_index ( ) , } , cs , ) // This should never happen. Either there's a bug in our config change // handling or the client corrupted the conf change. . map_err ( | err | panic ! ( " " cs err ) ) . unwrap ( ) ; equivalent ( cs , & self . switch_to_config ( cfg , prs ) ) . unwrap ( ) ; let pr = self . prs . progress . get_mut ( & self . id ) . unwrap ( ) ; pr . maybe_update ( pr . next - 1 ) ; // TODO(tbg): this is untested and likely unneeded info ! ( " " self id self raft_log committed self raft_log last_index ( ) self raft_log last_term ( ) s get_metadata ( ) get_index ( ) s get_metadata ( ) get_term ( ) ) ; true }
recovers the state machine from a snapshot.
recovers the state machine from a snapshot .
&mut self
s
&Snapshot