use crate::actors::ActorPath;
use crate::actors::ActorRef;
use crate::messaging::PathResolvable;
use sequence_trie::SequenceTrie;
use std::collections::HashMap;
use uuid::Uuid;
pub mod gc;
pub trait ActorLookup: Clone {
fn insert(&mut self, actor: ActorRef, path: PathResolvable) -> Option<ActorRef>;
fn contains(&self, path: &PathResolvable) -> bool;
fn get_by_actor_path(&self, path: &ActorPath) -> Option<&ActorRef> {
match path {
ActorPath::Unique(ref up) => self.get_by_uuid(up.uuid_ref()),
ActorPath::Named(ref np) => self.get_by_named_path(np.path_ref()),
}
}
fn get_by_uuid(&self, id: &Uuid) -> Option<&ActorRef>;
fn get_by_named_path(&self, path: &Vec<String>) -> Option<&ActorRef>;
fn get_mut_by_actor_path(&mut self, path: &ActorPath) -> Option<&mut ActorRef> {
match path {
ActorPath::Unique(ref up) => self.get_mut_by_uuid(up.uuid_ref()),
ActorPath::Named(ref np) => self.get_mut_by_named_path(np.path_ref()),
}
}
fn get_mut_by_uuid(&mut self, id: &Uuid) -> Option<&mut ActorRef>;
fn get_mut_by_named_path(&mut self, path: &Vec<String>) -> Option<&mut ActorRef>;
fn remove(&mut self, actor: ActorRef) -> usize;
fn remove_by_uuid(&mut self, id: &Uuid) -> bool;
fn remove_by_named_path(&mut self, path: &Vec<String>) -> bool;
fn cleanup(&mut self) -> usize {
0
}
}
#[derive(Clone)]
pub struct ActorStore {
uuid_map: HashMap<Uuid, ActorRef>,
name_map: SequenceTrie<String, ActorRef>,
}
impl ActorStore {
pub fn new() -> Self {
ActorStore {
uuid_map: HashMap::new(),
name_map: SequenceTrie::new(),
}
}
}
impl ActorLookup for ActorStore {
fn insert(&mut self, actor: ActorRef, path: PathResolvable) -> Option<ActorRef> {
match path {
PathResolvable::Path(actor_path) => match actor_path {
ActorPath::Unique(up) => {
let key = up.clone_id();
self.uuid_map.insert(key, actor)
}
ActorPath::Named(np) => {
let keys = np.path_ref();
self.name_map.insert(keys, actor)
}
},
PathResolvable::Alias(alias) => self.name_map.insert(&vec![alias], actor),
PathResolvable::ActorId(uuid) => self.uuid_map.insert(uuid, actor),
PathResolvable::System => {
panic!("System paths should not be registered");
}
}
}
fn contains(&self, path: &PathResolvable) -> bool {
match path {
PathResolvable::Path(actor_path) => match actor_path {
ActorPath::Unique(ref up) => self.uuid_map.contains_key(up.uuid_ref()),
ActorPath::Named(ref np) => {
let keys = np.path_ref();
self.name_map.get(keys).is_some()
}
},
PathResolvable::Alias(ref alias) => {
self.name_map.get(&[alias.clone()]).is_some()
}
PathResolvable::ActorId(ref uuid) => self.uuid_map.contains_key(uuid),
&PathResolvable::System => false, }
}
fn get_by_uuid(&self, id: &Uuid) -> Option<&ActorRef> {
self.uuid_map.get(id)
}
fn get_by_named_path(&self, path: &Vec<String>) -> Option<&ActorRef> {
self.name_map.get(path)
}
fn get_mut_by_uuid(&mut self, id: &Uuid) -> Option<&mut ActorRef> {
self.uuid_map.get_mut(id)
}
fn get_mut_by_named_path(&mut self, path: &Vec<String>) -> Option<&mut ActorRef> {
self.name_map.get_mut(path)
}
fn remove(&mut self, actor: ActorRef) -> usize {
let mut num_deleted = 0;
num_deleted += self.remove_from_uuid_map(&actor);
num_deleted += self.remove_from_name_map(&actor);
num_deleted
}
fn remove_by_uuid(&mut self, id: &Uuid) -> bool {
self.uuid_map.remove(id).is_some()
}
fn remove_by_named_path(&mut self, path: &Vec<String>) -> bool {
let existed = self.name_map.get(path).is_some();
self.name_map.remove(path);
existed
}
fn cleanup(&mut self) -> usize {
self.remove_deallocated_entries()
}
}
impl ActorStore {
fn remove_from_uuid_map(&mut self, actor: &ActorRef) -> usize {
let matches: Vec<_> = self
.uuid_map
.iter()
.filter(|rec| rec.1 == actor)
.map(|rec| rec.0.clone())
.collect();
let existed = matches.len();
for m in matches {
self.uuid_map.remove(&m);
}
existed
}
fn remove_from_name_map(&mut self, actor: &ActorRef) -> usize {
let matches: Vec<_> = self
.name_map
.iter()
.filter(|rec| rec.1 == actor)
.map(|(key, _)| {
let mut cl = Vec::new();
for k in key {
cl.push(k.clone());
}
cl
})
.collect();
let existed = matches.len();
for m in matches {
self.name_map.remove(&m);
}
existed
}
fn remove_deallocated_entries(&mut self) -> usize {
let mut existed = 0;
let matches: Vec<_> = self
.name_map
.iter()
.filter(|&(_, actor)| !actor.can_upgrade_component())
.map(|(key, _)| {
let mut cl = Vec::new();
for k in key {
cl.push(k.clone());
}
cl
})
.collect();
existed += matches.len();
for m in matches {
self.name_map.remove(&m);
}
let matches: Vec<_> = self
.uuid_map
.iter()
.filter(|&(_, actor)| !actor.can_upgrade_component())
.map(|(key, _)| key.clone())
.collect();
existed += matches.len();
for m in matches {
self.uuid_map.remove(&m);
}
existed
}
}