use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
use crate::events::status::Generation;
const SYSTEM_BITS: u32 = 64;
const LOCAL_BITS: u32 = 32;
const GENERATION_BITS: u32 = 32;
const LOCAL_SHIFT: u32 = GENERATION_BITS;
const SYSTEM_SHIFT: u32 = LOCAL_SHIFT + LOCAL_BITS;
const SYSTEM_MASK: u128 = ((1u128 << SYSTEM_BITS) - 1) << SYSTEM_SHIFT;
const LOCAL_MASK: u128 = ((1u128 << LOCAL_BITS) - 1) << LOCAL_SHIFT;
const GENERATION_MASK: u128 = (1u128 << GENERATION_BITS) - 1;
pub(crate) const LOCAL_FLAG: u32 = 1 << 31;
pub(crate) const INDEX_COUNTER_MASK: u32 = LOCAL_FLAG - 1;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct EventHandle(u128);
impl EventHandle {
pub(crate) fn new(system_id: u64, local_index: u32, generation: Generation) -> Self {
let raw = ((system_id as u128) << SYSTEM_SHIFT)
| ((local_index as u128) << LOCAL_SHIFT)
| (generation as u128);
Self(raw)
}
pub fn from_raw(raw: u128) -> Self {
Self(raw)
}
pub fn raw(&self) -> u128 {
self.0
}
pub fn system_id(&self) -> u64 {
((self.0 & SYSTEM_MASK) >> SYSTEM_SHIFT) as u64
}
pub fn local_index(&self) -> u32 {
((self.0 & LOCAL_MASK) >> LOCAL_SHIFT) as u32
}
pub fn generation(&self) -> Generation {
(self.0 & GENERATION_MASK) as Generation
}
pub fn is_local(&self) -> bool {
(self.local_index() & LOCAL_FLAG) != 0
}
pub fn is_distributed(&self) -> bool {
!self.is_local()
}
pub(crate) fn index_counter(&self) -> u32 {
self.local_index() & INDEX_COUNTER_MASK
}
pub fn with_generation(&self, generation: Generation) -> Self {
Self::new(self.system_id(), self.local_index(), generation)
}
}
impl Display for EventHandle {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
f,
"EventHandle {{ system={}, index={}, generation={}, {} }}",
self.system_id(),
self.index_counter(),
self.generation(),
if self.is_local() {
"local"
} else {
"distributed"
}
)
}
}