use crate::{
layer::{self, Layer, LayerBuilder, Selection, ViewBuilder},
Gossip, Profile, Profiles, Topic,
};
use keynesis::key::ed25519;
use std::{net::SocketAddr, sync::Arc};
pub struct Topology {
view_layers: Vec<Box<dyn Layer>>,
gossip_layers: Vec<Box<dyn Layer>>,
profile: Profile,
profiles: Profiles,
}
struct DefaultBuilder;
impl LayerBuilder for DefaultBuilder {
fn build_for_view(&self) -> Vec<Box<dyn Layer>> {
let mut layers: Vec<Box<dyn Layer>> = Vec::with_capacity(3);
layers.push(Box::new(layer::Rings::new(4)));
layers.push(Box::new(layer::Vicinity::new(20)));
layers.push(Box::new(layer::Cyclon::new(20)));
layers
}
fn build_for_gossip(&self) -> Vec<Box<dyn Layer>> {
let mut layers: Vec<Box<dyn Layer>> = Vec::with_capacity(3);
layers.push(Box::new(layer::Rings::new(10)));
layers.push(Box::new(layer::Vicinity::new(10)));
layers.push(Box::new(layer::Cyclon::new(10)));
layers
}
}
impl Topology {
pub fn new(address: SocketAddr, id: &ed25519::SecretKey) -> Self {
Self::new_with(address, id, DefaultBuilder)
}
pub fn new_with<LB>(address: SocketAddr, id: &ed25519::SecretKey, builder: LB) -> Self
where
LB: LayerBuilder,
{
let profile = Profile::new(address, id);
Self {
view_layers: builder.build_for_view(),
gossip_layers: builder.build_for_gossip(),
profile,
profiles: Profiles::new(512, 256, 128),
}
}
pub fn update_profile_subscriptions(&mut self, id: &ed25519::SecretKey) {
self.profile.clear_subscriptions();
for layer in self.view_layers.iter_mut() {
layer.subscriptions(self.profile.subscriptions_mut());
}
self.profile.commit_gossip(id);
}
pub fn subscribe_topic(&mut self, topic: Topic) {
for layer in self.view_layers.iter_mut() {
layer.subscribe(topic);
}
}
pub fn unsubscribe_topic(&mut self, topic: &Topic) {
for layer in self.view_layers.iter_mut() {
layer.unsubscribe(topic);
}
self.profile.unsubscribe(topic);
}
pub fn remove_peer(&mut self, id: &ed25519::PublicKey) {
for layer in self.view_layers.iter_mut() {
layer.remove(id);
}
self.profiles.demote(id);
}
pub fn promote_peer(&mut self, id: &ed25519::PublicKey) {
self.profiles.promote(id)
}
pub fn add_peer(&mut self, peer: Profile) -> bool {
let id = peer.id();
let peer = Arc::new(peer);
if !self.profiles.put(id, Arc::clone(&peer)) {
return false;
}
for layer in self.view_layers.iter_mut() {
layer.populate(&self.profile, &peer);
}
true
}
pub fn gossips_for(&mut self, recipient: &ed25519::PublicKey) -> Vec<Gossip> {
let mut gossips = Vec::with_capacity(1024);
let recipient = if let Some(recipient) = self.profiles.get(recipient) {
Arc::clone(recipient)
} else {
return gossips;
};
let id = recipient.id();
for layer in self.gossip_layers.iter_mut() {
layer.reset();
}
for subscription in recipient.subscriptions().iter() {
for layer in self.gossip_layers.iter_mut() {
layer.subscribe(subscription.topic());
}
}
for profile in self.view(None, Selection::Any) {
for layer in self.gossip_layers.iter_mut() {
layer.populate(recipient.as_ref(), &profile);
}
}
let mut builder = ViewBuilder::new(Selection::Any);
for layer in self.gossip_layers.iter_mut() {
layer.view(&mut builder);
}
let mut keys = builder.build();
keys.remove(&id);
for key in keys {
if let Some(profile) = self.profiles.get(&key) {
gossips.push(profile.gossip().clone());
} else {
unreachable!()
}
}
gossips.push(self.profile.gossip().clone());
gossips
}
pub fn view(
&mut self,
from: Option<&ed25519::PublicKey>,
selection: Selection,
) -> Vec<Arc<Profile>> {
let mut builder = ViewBuilder::new(selection);
if let Some(origin) = from {
builder.with_origin(*origin);
}
for layer in self.view_layers.iter_mut() {
layer.view(&mut builder);
}
let keys = builder.build();
let mut profiles = Vec::with_capacity(keys.len());
for key in keys {
if let Some(profile) = self.profiles.get(&key) {
profiles.push(Arc::clone(profile));
}
}
profiles
}
pub fn get(&mut self, id: &ed25519::PublicKey) -> Option<&Arc<Profile>> {
self.profiles.get(id)
}
}