use crate::kairos::Kairos;
use crate::metis::{Event, Gate, Ideal, ReleaseDrivenGate, VersionVector};
use core::num::NonZeroUsize;
pub(super) struct Quorum;
impl Gate for Quorum {
type Dep = u64;
type Progress = VersionVector;
fn deliverable(progress: &VersionVector, _sender: u32, required: &u64) -> bool {
u64::try_from(progress.iter().count()).unwrap_or(u64::MAX) >= *required
}
fn advance(progress: &mut VersionVector, sender: u32, _required: &u64) {
progress.observe(sender, 1);
}
fn stale(_progress: &VersionVector, _sender: u32, _required: &u64) -> bool {
false
}
}
impl ReleaseDrivenGate for Quorum {}
#[test]
fn test_quorum_gate_releases_on_threshold() {
let mut buf: Ideal<&str, Quorum> = Ideal::default();
buf.insert(Event {
stamp: Kairos::new(30, 0, 3, 0u16),
deps: 2,
payload: "third",
});
buf.insert(Event {
stamp: Kairos::new(20, 0, 2, 0u16),
deps: 1,
payload: "second",
});
buf.insert(Event {
stamp: Kairos::new(10, 0, 1, 0u16),
deps: 0,
payload: "first",
});
assert_eq!(buf.pop_ready(), Some("first"));
assert_eq!(buf.pop_ready(), Some("second"));
assert_eq!(buf.pop_ready(), Some("third"));
assert_eq!(buf.pop_ready(), None);
}
#[test]
fn test_try_insert_quorum_is_a_hard_cap() {
let cap = NonZeroUsize::new(1).unwrap();
let mut buf: Ideal<&str, Quorum> = Ideal::default();
let waiting = Event {
stamp: Kairos::new(10, 0, 1, 0u16),
deps: 2,
payload: "a",
};
assert!(buf.try_insert(waiting, cap).is_ok());
let before = buf.pending_len();
let rejected = buf
.try_insert(
Event {
stamp: Kairos::new(20, 0, 2, 0u16),
deps: 2,
payload: "b",
},
cap,
)
.unwrap_err();
assert_eq!(rejected.event.payload, "b");
assert_eq!(buf.pending_len(), before);
}