1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::{Address, GossipsBuilder, Layer, NodeProfile, Nodes, ViewBuilder};
use rand::{seq::IteratorRandom, Rng};
use std::collections::HashSet;
const CYCLON_MAX_VIEW_LENGTH: usize = 20;
const CYCLON_MAX_GOSSIPING_LENGTH: usize = 10;
#[derive(Clone, Debug)]
pub struct Cyclon {
view: Vec<Address>,
max_view_length: usize,
max_gossip_length: usize,
}
impl Cyclon {
pub fn new(max_view_length: usize, max_gossip_length: usize) -> Self {
Self {
view: Vec::with_capacity(max_view_length),
max_view_length,
max_gossip_length,
}
}
fn populate_random<R>(&mut self, mut rng: R, known_nodes: &HashSet<Address>, capacity: usize)
where
R: Rng,
{
self.view = known_nodes
.iter()
.map(|v| v)
.cloned()
.choose_multiple(&mut rng, capacity);
}
}
impl Default for Cyclon {
fn default() -> Self {
Self::new(CYCLON_MAX_VIEW_LENGTH, CYCLON_MAX_GOSSIPING_LENGTH)
}
}
impl Layer for Cyclon {
fn alias(&self) -> &'static str {
"cyclon"
}
fn reset(&mut self) {
self.view.clear()
}
fn populate(&mut self, _identity: &NodeProfile, all_nodes: &Nodes) {
self.populate_random(
rand::thread_rng(),
all_nodes.available_nodes(),
self.max_view_length,
)
}
fn gossips(
&mut self,
_identity: &NodeProfile,
gossips_builder: &mut GossipsBuilder,
all_nodes: &Nodes,
) {
let mut cyclon = Cyclon::new(self.max_gossip_length, 0);
cyclon.populate_random(
rand::thread_rng(),
all_nodes.available_nodes(),
self.max_gossip_length,
);
cyclon.view.into_iter().for_each(|node| {
gossips_builder.add(node);
})
}
fn view(&mut self, view_builder: &mut ViewBuilder, all_nodes: &mut Nodes) {
for id in self.view.iter() {
if let Some(node) = all_nodes.peek_mut(id) {
view_builder.add(node)
}
}
}
}