use std::cell::RefCell;
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha8Rng;
use crate::swarm::Swarm;
use crate::traits::Topology;
#[derive(Debug)]
pub struct Random {
k: usize,
rng: RefCell<ChaCha8Rng>,
}
impl Random {
pub fn new(k: usize, seed: u64) -> Self {
assert!(k >= 1, "Random topology needs k >= 1 informants");
Self {
k,
rng: RefCell::new(ChaCha8Rng::seed_from_u64(seed)),
}
}
}
impl Topology for Random {
fn neighbors(&self, i: usize, swarm: &Swarm) -> Vec<usize> {
let n = swarm.len();
let want = self.k.min(n.saturating_sub(1));
let mut idx = Vec::with_capacity(want + 1);
idx.push(i);
let mut rng = self.rng.borrow_mut();
while idx.len() < want + 1 {
let j = rng.gen_range(0..n);
if !idx.contains(&j) {
idx.push(j);
}
}
idx
}
}