quorum_set/quorum/
quorum_set_impl.rs1use std::collections::BTreeSet;
2
3use crate::Node;
4use crate::QuorumTree;
5use crate::quorum::quorum_set::QuorumSet;
6
7impl<ID> QuorumSet for BTreeSet<ID>
12where ID: PartialOrd + Ord + Clone + 'static
13{
14 type Id = ID;
15 type Iter = std::collections::btree_set::IntoIter<ID>;
16
17 fn is_quorum<'a, I: Iterator<Item = &'a ID> + Clone>(&self, ids: I) -> bool {
18 let mut count = 0;
19 let limit = self.len();
20 for id in self {
21 if ids.clone().any(|candidate| candidate == id) {
22 count += 2;
23 if count > limit {
24 return true;
25 }
26 }
27 }
28 false
29 }
30
31 fn ids(&self) -> Self::Iter {
32 self.clone().into_iter()
33 }
34}
35
36impl<NID> QuorumSet for Vec<BTreeSet<NID>>
41where NID: PartialOrd + Ord + Clone + 'static
42{
43 type Id = NID;
44 type Iter = std::collections::btree_set::IntoIter<NID>;
45
46 fn is_quorum<'a, I: Iterator<Item = &'a NID> + Clone>(&self, ids: I) -> bool {
47 for config in self {
48 if !config.is_quorum(ids.clone()) {
49 return false;
50 }
51 }
52 true
53 }
54
55 fn ids(&self) -> Self::Iter {
56 let mut ids = BTreeSet::new();
57 for config in self {
58 ids.extend(config.iter().cloned());
59 }
60 ids.into_iter()
61 }
62}
63
64impl<ID> QuorumSet for QuorumTree<ID>
69where ID: Ord + Clone + 'static
70{
71 type Id = ID;
72 type Iter = std::collections::btree_set::IntoIter<ID>;
73
74 fn is_quorum<'a, I: Iterator<Item = &'a ID> + Clone>(&self, ids: I) -> bool {
75 self.spec.is_quorum(ids)
76 }
77
78 fn ids(&self) -> Self::Iter {
79 let mut ids = BTreeSet::new();
80 collect_tree_ids(self, &mut ids);
81 ids.into_iter()
82 }
83}
84
85fn collect_tree_ids<ID>(tree: &QuorumTree<ID>, ids: &mut BTreeSet<ID>)
86where ID: Ord + Clone {
87 for node in tree.children() {
88 match node {
89 Node::Id(id) => {
90 ids.insert(id.clone());
91 }
92 Node::Subtree(subtree) => {
93 collect_tree_ids(subtree, ids);
94 }
95 }
96 }
97}