dope-core 0.15.1

The manifold runtime
Documentation
use core::{marker, mem, num};

use o3::{collections::slab::external, num::bounded};

use crate::driver::route::{self, table};

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[repr(C)]
pub struct Token {
    epoch: num::NonZeroU64,
    meta: u64,
    marker: marker::PhantomData<*mut ()>,
}

pub trait Private {}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[repr(transparent)]
pub struct SlotIndex(BoundedSlotIndex);

type BoundedSlotIndex = bounded::U32<0, { route::SLOT_MASK as u32 }>;

impl SlotIndex {
    pub const ZERO: Self = Self(BoundedSlotIndex::clamp_from_usize(0));

    pub const fn try_new(raw: u32) -> Option<Self> {
        match BoundedSlotIndex::new(raw) {
            Some(raw) => Some(Self(raw)),
            None => None,
        }
    }

    pub(crate) const fn from_bounded(raw: u32) -> Self {
        debug_assert!((raw as u64) <= route::SLOT_MASK);
        Self(BoundedSlotIndex::clamp_from_usize(raw as usize))
    }

    pub const fn raw(self) -> u32 {
        self.0.get()
    }
}

impl Default for SlotIndex {
    fn default() -> Self {
        Self::ZERO
    }
}

impl From<u16> for SlotIndex {
    fn from(raw: u16) -> Self {
        Self::from_bounded(raw as u32)
    }
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[repr(transparent)]
pub struct Epoch(BoundedEpoch, marker::PhantomData<*mut ()>);

type BoundedEpoch = num::NonZeroU64;

impl Epoch {
    pub const INITIAL: Self = Self(BoundedEpoch::MIN, marker::PhantomData);

    pub const fn new(raw: u64) -> Option<Self> {
        match BoundedEpoch::new(raw) {
            Some(_) if raw > route::EPOCH_MASK => None,
            Some(epoch) => Some(Self(epoch, marker::PhantomData)),
            None => None,
        }
    }

    pub const fn raw(self) -> u64 {
        self.0.get()
    }

    pub const fn next(self) -> Option<Self> {
        match self.raw().checked_add(1) {
            Some(raw) => Self::new(raw),
            None => None,
        }
    }
}

impl From<num::NonZeroU16> for Epoch {
    fn from(raw: num::NonZeroU16) -> Self {
        Self(raw.into(), marker::PhantomData)
    }
}

impl external::Generation for Epoch {
    const INITIAL: Self = Self::INITIAL;

    fn next(self) -> Option<Self> {
        match self.raw().checked_add(1) {
            Some(raw) => Self::new(raw),
            None => None,
        }
    }
}

const _: () = {
    assert!(mem::size_of::<SlotIndex>() == mem::size_of::<u32>());
    assert!(mem::size_of::<Epoch>() == mem::size_of::<u64>());
    assert!(mem::size_of::<Option<Epoch>>() == mem::size_of::<u64>());
};

impl Token {
    pub const fn new(route: u8, slot: route::SlotIndex, epoch: route::Epoch) -> Self {
        Self::from_components(route, 0, slot, epoch.raw())
    }

    pub const fn framework(slot: route::SlotIndex) -> Self {
        Self::from_components(route::FRAMEWORK, 0, slot, 0)
    }

    pub const fn with_kind(self, kind: u8) -> Self {
        Self {
            meta: (self.meta & !(0xFF << route::KIND_SHIFT)) | ((kind as u64) << route::KIND_SHIFT),
            ..self
        }
    }

    const fn from_components(route: u8, kind: u8, slot: route::SlotIndex, epoch: u64) -> Self {
        debug_assert!(epoch <= route::EPOCH_MASK);
        Self {
            epoch: unsafe { num::NonZeroU64::new_unchecked(epoch + 1) },
            meta: ((route as u64) << route::SHIFT)
                | ((kind as u64) << route::KIND_SHIFT)
                | slot.raw() as u64,
            marker: marker::PhantomData,
        }
    }

    pub(crate) const fn try_from_framework_raw(raw: u64) -> Option<Self> {
        if raw == 0 {
            return None;
        }
        let route = (raw >> route::SHIFT) as u8;
        let kind = (raw >> route::KIND_SHIFT) as u8;
        match route::SlotIndex::try_new((raw & route::SLOT_MASK) as u32) {
            Some(slot) => Some(Self::from_components(route, kind, slot, 0)),
            None => None,
        }
    }

    pub(crate) const fn framework_raw(self) -> u64 {
        debug_assert!(self.epoch_raw() == 0);
        self.meta
    }

    pub const fn route(self) -> u8 {
        (self.meta >> route::SHIFT) as u8
    }

    pub const fn kind(self) -> u8 {
        (self.meta >> route::KIND_SHIFT) as u8
    }

    pub const fn slot(self) -> route::SlotIndex {
        route::SlotIndex::from_bounded((self.meta & route::SLOT_MASK) as u32)
    }

    pub const fn epoch(self) -> Option<route::Epoch> {
        route::Epoch::new(self.epoch_raw())
    }

    pub const fn epoch_raw(self) -> u64 {
        self.epoch.get() - 1
    }

    pub const fn same_target(self, other: Self) -> bool {
        self.epoch.get() == other.epoch.get()
            && self.route() == other.route()
            && self.slot().raw() == other.slot().raw()
    }

    pub const fn parts<Tag: route::Tag>(self) -> Option<table::Parts<Tag>> {
        if self.route() != Tag::ROUTE || (Tag::KIND != 0 && self.kind() != Tag::KIND) {
            return None;
        }
        table::Parts::new(self.slot().raw(), self.epoch_raw())
    }

    pub const fn from_key<Tag: route::Tag>(key: table::Key<Tag>) -> Self {
        Self::from_components(Tag::ROUTE, Tag::KIND, key.slot(), key.epoch().raw())
    }

    pub const fn from_target<Tag: route::Tag>(target: route::Target<'_, Tag>) -> Self {
        Self::from_parts(target.parts())
    }

    #[doc(hidden)]
    pub const fn from_parts<Tag: route::Tag>(parts: table::Parts<Tag>) -> Self {
        Self::from_components(Tag::ROUTE, Tag::KIND, parts.slot(), parts.epoch().raw())
    }
}

impl<Tag: route::Tag> From<route::Target<'_, Tag>> for Token {
    fn from(target: route::Target<'_, Tag>) -> Self {
        Self::from_target(target)
    }
}