use std::collections::HashSet;
use std::hash::Hash;
use std::net::IpAddr;
use std::sync::atomic::Ordering;
use std::time::{Duration, Instant};
use ipnet::IpNet;
use tracing::warn;
use crate::bounds::{Key, Value};
use crate::replicated_map::MAX_NETS;
use super::{derive_local_net, Replica};
impl<K: Key + Hash, V: Value> Replica<K, V> {
pub(crate) fn set_nets(&self, nets: &[IpNet]) {
let nets = nets.to_vec();
let local = derive_local_net(&nets, self.listen_addr);
*self.local_net.write() = local;
*self.nets.write() = nets;
}
pub(crate) fn add_net(&self, net: IpNet) -> bool {
let mut guard = self.nets.write();
if guard.contains(&net) {
return true;
}
if guard.len() >= MAX_NETS {
warn!("cannot add network {net}: already at the maximum of {MAX_NETS} networks");
return false;
}
guard.push(net);
*self.local_net.write() = derive_local_net(&guard, self.listen_addr);
true
}
pub(crate) fn remove_net(&self, net: IpNet) -> bool {
let mut guard = self.nets.write();
let before = guard.len();
guard.retain(|n| *n != net);
let removed = guard.len() != before;
if removed {
*self.local_net.write() = derive_local_net(&guard, self.listen_addr);
}
removed
}
pub(crate) fn nets(&self) -> Vec<IpNet> {
self.nets.read().clone()
}
pub(crate) fn local_net(&self) -> IpNet {
*self.local_net.read()
}
pub(crate) fn set_remote_interval(&self, interval: u32) {
self.remote_interval.store(interval, Ordering::Relaxed);
}
pub(crate) fn set_remote_fanout(&self, fanout: usize) {
self.remote_fanout.store(fanout, Ordering::Relaxed);
}
pub(crate) fn set_reconcile_interval(&self, interval: Duration) {
*self.reconcile_interval.write() = interval;
}
pub(crate) fn decommission_peer(&self, peer: IpAddr) {
self.members.write().remove(&peer);
self.peers.write().remove(&peer);
for key_acks in self.tombstone_acks.write().values_mut() {
key_acks.remove(&peer);
}
}
pub(crate) fn seed_peer(&self, peer: IpAddr) {
self.peers.write().insert(peer, Instant::now());
}
pub(crate) fn members_snapshot(&self) -> HashSet<IpAddr> {
self.members.read().clone()
}
#[cfg(any(test, feature = "internal-testing"))]
pub(crate) fn peers_map_len(&self) -> usize {
self.peers.read().len()
}
#[cfg(any(test, feature = "internal-testing"))]
pub(crate) fn replay_filter_len(&self) -> usize {
self.replay_filter.len()
}
#[cfg(any(test, feature = "internal-testing"))]
pub(crate) fn tombstone_acks_len(&self) -> usize {
self.tombstone_acks.read().len()
}
#[cfg(any(test, feature = "internal-testing"))]
pub(crate) fn bulk_dumps_in_flight_count(&self) -> usize {
self.bulk_dumps_in_flight.load(Ordering::Acquire)
}
pub(crate) fn listen_addr(&self) -> IpAddr {
self.listen_addr
}
}