use std::fmt::{self, Debug};
use std::sync::Arc;
use ahash::RandomState;
use dashmap::{DashMap, Entry};
use acktor::{Recipient, Sender, SenderId};
use crate::remote_message::RemoteMessage;
#[derive(Clone, Default)]
pub struct RemoteActorRegistry {
inner: Arc<DashMap<u64, Recipient<RemoteMessage>, RandomState>>,
}
impl Debug for RemoteActorRegistry {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut list = f.debug_list();
for entry in self.inner.iter() {
list.entry(entry.key());
}
list.finish()
}
}
impl RemoteActorRegistry {
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: Arc::new(DashMap::with_capacity_and_hasher(
capacity,
RandomState::new(),
)),
}
}
pub fn insert<A>(&self, actor: A) -> bool
where
A: Into<Recipient<RemoteMessage>>,
{
let recipient = actor.into();
let index = recipient.index();
match self.inner.entry(index) {
Entry::Vacant(e) => {
e.insert(recipient);
true
}
Entry::Occupied(_) => false,
}
}
pub fn remove(&self, index: u64) -> Option<Recipient<RemoteMessage>> {
self.inner.remove(&index).map(|(_, recipient)| recipient)
}
pub fn get(&self, index: u64) -> Option<Recipient<RemoteMessage>> {
let recipient = self.inner.get(&index)?;
if !recipient.is_closed() {
return Some(recipient.clone());
}
drop(recipient);
self.inner.remove_if(&index, |_, r| r.is_closed());
None
}
pub fn contains(&self, index: u64) -> bool {
self.inner.contains_key(&index)
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn retain<F>(&self, mut predicate: F)
where
F: FnMut(u64, &Recipient<RemoteMessage>) -> bool,
{
self.inner
.retain(|index, recipient| predicate(*index, recipient));
}
}