#![allow(dead_code)]
use super::changer::Changer;
use crate::eraftpb::{ConfChangeSingle, ConfChangeType, ConfState};
use crate::tracker::ProgressTracker;
use crate::Result;
fn to_conf_change_single(cs: &ConfState) -> (Vec<ConfChangeSingle>, Vec<ConfChangeSingle>) {
let mut incoming = Vec::new();
let mut outgoing = Vec::new();
for id in cs.get_voters_outgoing() {
outgoing.push(raft_proto::new_conf_change_single(
*id,
ConfChangeType::AddNode,
));
}
for id in cs.get_voters_outgoing() {
incoming.push(raft_proto::new_conf_change_single(
*id,
ConfChangeType::RemoveNode,
));
}
for id in cs.get_voters() {
incoming.push(raft_proto::new_conf_change_single(
*id,
ConfChangeType::AddNode,
));
}
for id in cs.get_learners() {
incoming.push(raft_proto::new_conf_change_single(
*id,
ConfChangeType::AddLearnerNode,
));
}
for id in cs.get_learners_next() {
incoming.push(raft_proto::new_conf_change_single(
*id,
ConfChangeType::AddLearnerNode,
));
}
(outgoing, incoming)
}
pub fn restore(tracker: &mut ProgressTracker, next_idx: u64, cs: &ConfState) -> Result<()> {
let (outgoing, incoming) = to_conf_change_single(cs);
if outgoing.is_empty() {
for i in incoming {
let (cfg, changes) = Changer::new(tracker).simple(&[i])?;
tracker.apply_conf(cfg, changes, next_idx);
}
} else {
for cc in outgoing {
let (cfg, changes) = Changer::new(tracker).simple(&[cc])?;
tracker.apply_conf(cfg, changes, next_idx);
}
let (cfg, changes) = Changer::new(tracker).enter_joint(cs.auto_leave, &incoming)?;
tracker.apply_conf(cfg, changes, next_idx);
}
Ok(())
}