use std::cmp::Ordering;
use crate::vote::RaftLeaderId;
pub struct LeaderIdCompare;
impl LeaderIdCompare {
pub fn std<LID>(a: &LID, b: &LID) -> Option<Ordering>
where LID: RaftLeaderId {
match a.term().cmp(&b.term()) {
Ordering::Equal => {
if a.node_id() == b.node_id() {
Some(Ordering::Equal)
} else {
None
}
}
cmp => Some(cmp),
}
}
pub fn adv<LID>(a: &LID, b: &LID) -> Option<Ordering>
where LID: RaftLeaderId {
let res = (a.term(), a.node_id()).cmp(&(b.term(), b.node_id()));
Some(res)
}
}
#[cfg(test)]
mod tests {
use std::cmp::Ordering;
use crate::vote::RaftLeaderId;
#[derive(Debug, PartialEq, Eq, Clone, PartialOrd, derive_more::Display)]
#[display("T{}-N{}", _0, _1)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
struct LeaderId(u64, u64);
impl PartialEq<u64> for LeaderId {
fn eq(&self, _other: &u64) -> bool {
false
}
}
impl PartialOrd<u64> for LeaderId {
fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
self.0.partial_cmp(other)
}
}
impl RaftLeaderId for LeaderId {
type Term = u64;
type NodeId = u64;
type Committed = u64;
fn new(term: u64, node_id: u64) -> Self {
Self(term, node_id)
}
fn term(&self) -> u64 {
self.0
}
fn node_id(&self) -> &u64 {
&self.1
}
fn to_committed(&self) -> Self::Committed {
self.0
}
}
#[test]
fn test_std_cmp() {
use Ordering::*;
use super::LeaderIdCompare as Cmp;
let lid = |term, node_id| LeaderId(term, node_id);
assert_eq!(Cmp::std(&lid(2, 2), &lid(1, 2)), Some(Greater));
assert_eq!(Cmp::std(&lid(1, 2), &lid(2, 2)), Some(Less));
assert_eq!(Cmp::std(&lid(2, 2), &lid(2, 2)), Some(Equal));
assert_eq!(Cmp::std(&lid(2, 2), &lid(2, 1)), None);
assert_eq!(Cmp::std(&lid(2, 1), &lid(2, 2)), None);
assert_eq!(Cmp::std(&lid(2, 2), &lid(2, 3)), None);
}
#[test]
fn test_adv_cmp() {
use Ordering::*;
use super::LeaderIdCompare as Cmp;
let lid = |term, node_id| LeaderId(term, node_id);
assert_eq!(Cmp::adv(&lid(2, 2), &lid(1, 2)), Some(Greater));
assert_eq!(Cmp::adv(&lid(1, 2), &lid(2, 2)), Some(Less));
assert_eq!(Cmp::adv(&lid(2, 2), &lid(2, 1)), Some(Greater));
assert_eq!(Cmp::adv(&lid(2, 1), &lid(2, 2)), Some(Less));
assert_eq!(Cmp::adv(&lid(2, 2), &lid(2, 2)), Some(Equal));
}
}