use hashring::HashRing;
use std::collections::HashMap;
use std::hash::Hash;
use uuid::Uuid;
pub struct RemoteNodeStore {
nodes: HashMap<Uuid, RemoteNode>,
table: HashRing<RemoteNode>,
}
#[derive(Hash, Serialize, Deserialize, Debug, Clone)]
pub struct RemoteNode {
pub id: Uuid,
pub addr: String,
}
impl RemoteNodeStore {
pub fn new(nodes: Vec<RemoteNode>) -> RemoteNodeStore {
let mut table = HashRing::new();
let nodes = nodes
.into_iter()
.map(|n| {
table.add(n.clone());
(n.id, n)
})
.collect();
RemoteNodeStore { table, nodes }
}
pub fn get(&self, node_id: &Uuid) -> Option<&RemoteNode> {
self.nodes.get(node_id)
}
pub fn is_registered(&self, node_id: Uuid) -> bool {
self.nodes.contains_key(&node_id)
}
pub fn remove(&mut self, node_id: &Uuid) -> Option<RemoteNode> {
self.nodes
.remove(&node_id)
.and_then(|node| self.table.remove(&node))
}
pub fn get_by_key(&mut self, key: impl Hash) -> Option<&RemoteNode> {
self.table.get(&key)
}
pub fn add(&mut self, node: RemoteNode) {
let mut nodes = self.get_all();
nodes.push(node);
nodes.sort_by(|a, b| a.id.partial_cmp(&b.id).unwrap());
self.table = HashRing::new();
self.nodes = nodes
.into_iter()
.map(|n| {
self.table.add(n.clone());
(n.id, n)
})
.collect();
}
pub fn get_all(&self) -> Vec<RemoteNode> {
self.nodes.values().map(|m| m.clone()).collect()
}
}
impl RemoteNode {
pub fn new(id: Uuid, addr: String) -> RemoteNode {
RemoteNode { id, addr }
}
}
impl ToString for RemoteNode {
fn to_string(&self) -> String {
format!("{}|{}", self.addr, self.id)
}
}
impl PartialEq for RemoteNode {
fn eq(&self, other: &RemoteNode) -> bool {
self.id == other.id && self.addr == other.addr
}
}