use std::any::Any;
use std::sync::atomic::{AtomicI32, Ordering};
use crate::topology::Communicator;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct CommKeyval {
id: i32,
}
impl CommKeyval {
pub fn id(&self) -> i32 {
self.id
}
}
static NEXT_KEYVAL: AtomicI32 = AtomicI32::new(1);
pub fn create_keyval() -> CommKeyval {
CommKeyval {
id: NEXT_KEYVAL.fetch_add(1, Ordering::Relaxed),
}
}
pub trait CommunicatorAttributes: Communicator {
fn set_attr<T: Any + Send + Sync>(&self, key: &CommKeyval, value: T) {
self.comm_data()
.attributes
.lock()
.unwrap()
.insert(key.id, Box::new(value));
}
fn get_attr<T: Any + Clone>(&self, key: &CommKeyval) -> Option<T> {
self.comm_data()
.attributes
.lock()
.unwrap()
.get(&key.id)
.and_then(|b| b.downcast_ref::<T>())
.cloned()
}
fn has_attr(&self, key: &CommKeyval) -> bool {
self.comm_data()
.attributes
.lock()
.unwrap()
.contains_key(&key.id)
}
fn delete_attr(&self, key: &CommKeyval) {
self.comm_data().attributes.lock().unwrap().remove(&key.id);
}
}
impl<C: Communicator + ?Sized> CommunicatorAttributes for C {}
pub mod traits {
pub use super::CommunicatorAttributes;
}