use std::fmt::{self, Debug};
use std::sync::Arc;
use dashmap::{DashMap, Entry};
use acktor::SenderInfo;
use super::RemoteMailbox;
#[derive(Clone, Default)]
pub struct RemoteMailboxRegistry {
inner: Arc<DashMap<u64, RemoteMailbox, ahash::RandomState>>,
}
impl Debug for RemoteMailboxRegistry {
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()
}
}
#[allow(dead_code)]
impl RemoteMailboxRegistry {
#[inline]
pub fn new() -> Self {
Self::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
inner: Arc::new(DashMap::with_capacity_and_hasher(
capacity,
ahash::RandomState::new(),
)),
}
}
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn retain<F>(&self, mut predicate: F)
where
F: FnMut(u64, &RemoteMailbox) -> bool,
{
self.inner
.retain(|index, recipient| predicate(*index, recipient));
}
pub fn get(&self, index: u64) -> Option<RemoteMailbox> {
match self.inner.entry(index) {
Entry::Occupied(entry) => {
let recipient = entry.get();
if recipient.is_closed() {
entry.remove();
None
} else {
Some(recipient.clone())
}
}
Entry::Vacant(_) => None,
}
}
pub fn contains_index(&self, index: u64) -> bool {
match self.inner.entry(index) {
Entry::Occupied(entry) => {
if entry.get().is_closed() {
entry.remove();
false
} else {
true
}
}
Entry::Vacant(_) => false,
}
}
pub fn remove(&self, index: u64) -> Option<RemoteMailbox> {
self.inner.remove(&index).map(|(_, recipient)| recipient)
}
pub fn insert(&self, actor: RemoteMailbox) -> bool {
let index = actor.index().as_local();
match self.inner.entry(index) {
Entry::Occupied(_) => false,
Entry::Vacant(entry) => {
entry.insert(actor);
true
}
}
}
}