quorum_set/quorum/quorum_bridge_impl.rs
1use std::collections::BTreeSet;
2
3use crate::quorum::QuorumBridge;
4use crate::quorum::QuorumIntersection;
5
6/// Builds an intermediate joint quorum set for a target flat config.
7///
8/// The result is the target alone when [`QuorumIntersection::intersects_with`] proves that every
9/// quorum of `self` intersects every quorum of the target, e.g. when the target adds one voter to
10/// a uniform `self`. Otherwise it is the joint of the last config of `self` and the target.
11///
12/// A Raft-style caller that applies a target-alone result must first commit an entry of the
13/// leader's own term. Otherwise two leaders of different terms can each move from the same
14/// committed config to a different target, and the two targets can have disjoint quorums.
15impl<ID> QuorumBridge<BTreeSet<ID>> for Vec<BTreeSet<ID>>
16where ID: Ord + Clone
17{
18 fn bridge_to(&self, other: BTreeSet<ID>) -> Self {
19 let intersects = self.intersects_with(&other);
20 if intersects == Some(true) {
21 vec![other]
22 } else if let Some(last) = self.last() {
23 vec![last.clone(), other]
24 } else {
25 vec![other]
26 }
27 }
28}
29
30/// Builds an intermediate joint quorum set for a target joint config.
31///
32/// The result is the target alone when [`QuorumIntersection::intersects_with`] proves that every
33/// quorum of `self` intersects every quorum of the target. Otherwise it is the joint of the last
34/// config of `self` and the configs of the target. For a target that holds one config, the result
35/// equals the result for that config as a [`BTreeSet`] target.
36///
37/// A Raft-style caller that applies a target-alone result must first commit an entry of the
38/// leader's own term. Otherwise two leaders of different terms can each move from the same
39/// committed config to a different target, and the two targets can have disjoint quorums.
40impl<ID> QuorumBridge<Vec<BTreeSet<ID>>> for Vec<BTreeSet<ID>>
41where ID: Ord + Clone
42{
43 fn bridge_to(&self, other: Vec<BTreeSet<ID>>) -> Self {
44 let intersects = self.intersects_with(&other);
45 if intersects == Some(true) {
46 other
47 } else if let Some(last) = self.last() {
48 let mut joint = vec![last.clone()];
49 joint.extend(other);
50 joint
51 } else {
52 other
53 }
54 }
55}