use std::collections::BTreeSet;
use crate::quorum::QuorumIntersection;
impl<ID> QuorumIntersection<Vec<BTreeSet<ID>>> for Vec<BTreeSet<ID>>
where ID: Ord + Clone
{
fn intersects_with(&self, other: &Vec<BTreeSet<ID>>) -> Option<bool> {
let either_is_empty = self.is_empty() || other.is_empty();
if either_is_empty {
let empty_config = BTreeSet::new();
let holds_empty_config = self.contains(&empty_config) || other.contains(&empty_config);
return Some(holds_empty_config);
}
let both_uniform = self.len() == 1 && other.len() == 1;
if both_uniform {
return self[0].intersects_with(&other[0]);
}
for a in self {
for b in other {
let intersects = a.intersects_with(b);
if intersects == Some(true) {
return Some(true);
}
}
}
None
}
}
impl<ID> QuorumIntersection<BTreeSet<ID>> for BTreeSet<ID>
where ID: Ord + Clone
{
fn intersects_with(&self, other: &BTreeSet<ID>) -> Option<bool> {
let majority_self = self.len() / 2 + 1;
let majority_other = other.len() / 2 + 1;
let only_self = self.difference(other).count();
let only_other = other.difference(self).count();
let shared = self.intersection(other).count();
let need_self = majority_self.saturating_sub(only_self);
let need_other = majority_other.saturating_sub(only_other);
Some(need_self + need_other > shared)
}
}
impl<ID> QuorumIntersection<BTreeSet<ID>> for Vec<BTreeSet<ID>>
where ID: Ord + Clone
{
fn intersects_with(&self, other: &BTreeSet<ID>) -> Option<bool> {
if self.is_empty() {
return Some(other.is_empty());
}
let uniform = self.len() == 1;
if uniform {
return self[0].intersects_with(other);
}
for config in self {
let intersects = config.intersects_with(other);
if intersects == Some(true) {
return Some(true);
}
}
None
}
}
impl<ID> QuorumIntersection<Vec<BTreeSet<ID>>> for BTreeSet<ID>
where ID: Ord + Clone
{
fn intersects_with(&self, other: &Vec<BTreeSet<ID>>) -> Option<bool> {
other.intersects_with(self)
}
}