use std::io;
use std::net::IpAddr;
use std::ops::RangeBounds;
use ipnet::IpNet;
use crate::bounds::Key;
use crate::entry::State;
use crate::read_replica_map::ReadReplicaMap;
use crate::replicated_map::Config;
use rsos::Fingerprint;
pub struct ReadReplicaSet<K>(ReadReplicaMap<K, ()>);
impl<K> Clone for ReadReplicaSet<K> {
fn clone(&self) -> Self {
ReadReplicaSet(self.0.clone())
}
}
impl<K: Key> ReadReplicaSet<K> {
pub async fn new(config: Config) -> io::Result<Self> {
ReadReplicaMap::new(config).await.map(ReadReplicaSet)
}
#[must_use]
pub fn with_seed(self, peer: IpAddr) -> Self {
ReadReplicaSet(self.0.with_seed(peer))
}
pub fn set_net(&self, net: IpNet) {
self.0.set_net(net);
}
#[must_use]
pub fn net(&self) -> IpNet {
self.0.net()
}
pub fn set_on_update<F: Send + Sync + Fn(&K, &State<()>) + 'static>(&self, on_update: F) {
self.0.set_on_update(on_update);
}
#[must_use]
pub fn contains(&self, key: &K) -> bool {
self.0.contains_key(key)
}
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[must_use]
pub fn fingerprint<R: RangeBounds<K>>(&self, range: R) -> Fingerprint {
self.0.fingerprint(range)
}
#[must_use]
pub fn keys(&self) -> Vec<K> {
self.0.keys()
}
pub async fn start_reconciliation(&self, send_buf: &mut Vec<u8>) {
self.0.start_reconciliation(send_buf).await;
}
pub async fn run(self) {
self.0.run().await;
}
}
#[cfg(test)]
mod read_replica_set_tests {
use std::time::Duration;
use crate::read_replica_set::ReadReplicaSet;
use crate::replicated_map::{Config, MAX_NETS};
fn ephemeral_config() -> Config {
Config {
port: 0,
listen_addr: "127.0.0.1".parse().unwrap(),
nets: [None; MAX_NETS],
remote_interval: 6,
remote_fanout: 2,
cluster_key: None,
insecure_no_key: true,
node_id: None,
encrypt: false,
reconcile_interval: Duration::from_secs(1),
bulk_send_rate: Some(32 * 1024 * 1024),
recv_buffer_size: Some(8 * 1024 * 1024),
send_buffer_size: Some(8 * 1024 * 1024),
freshness_window: gossip::replay::FRESHNESS_WINDOW_DEFAULT,
max_peers: 1024,
max_concurrent_bulk_dumps: 4,
}
}
#[tokio::test]
async fn fresh_replica_has_no_members() {
let replica = ReadReplicaSet::<i32>::new(ephemeral_config())
.await
.unwrap();
assert!(replica.is_empty());
assert_eq!(replica.len(), 0);
assert!(!replica.contains(&1));
assert!(replica.keys().is_empty());
}
}