use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct ClusterId(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct NodeId(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Term(pub u64);
impl Term {
pub const ZERO: Term = Term(0);
#[must_use]
pub fn next(self) -> Term {
Term(self.0 + 1)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct LogIndex(pub u64);
#[derive(
Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, Default,
)]
pub struct LogPosition {
pub term: u64,
pub index: u64,
}
impl LogPosition {
pub const ZERO: LogPosition = LogPosition { term: 0, index: 0 };
#[must_use]
pub fn is_at_least_as_up_to_date_as(&self, other: &LogPosition) -> bool {
self >= other
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct HardState {
pub current_term: Term,
pub voted_for: Option<NodeId>,
}
impl Default for HardState {
fn default() -> Self {
Self {
current_term: Term::ZERO,
voted_for: None,
}
}
}
#[must_use]
pub fn quorum(n_voters: usize) -> usize {
n_voters / 2 + 1
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn log_position_ordering_is_raft_up_to_date_rule() {
let old_term_long = LogPosition { term: 1, index: 7 };
let new_term_short = LogPosition { term: 2, index: 5 };
assert!(new_term_short.is_at_least_as_up_to_date_as(&old_term_long));
assert!(!old_term_long.is_at_least_as_up_to_date_as(&new_term_short));
let a = LogPosition { term: 2, index: 9 };
let b = LogPosition { term: 2, index: 5 };
assert!(a.is_at_least_as_up_to_date_as(&b));
assert!(!b.is_at_least_as_up_to_date_as(&a));
assert!(b.is_at_least_as_up_to_date_as(&LogPosition { term: 2, index: 5 }));
}
#[test]
fn quorum_arithmetic() {
assert_eq!(quorum(1), 1);
assert_eq!(quorum(2), 2); assert_eq!(quorum(3), 2);
assert_eq!(quorum(4), 3);
assert_eq!(quorum(5), 3);
}
}