dope-core 0.15.1

The manifold runtime
Documentation
pub(crate) mod raw;

use std::{fmt, io, marker, mem, rc};

use o3::collections::completion::narrow;

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

type Invariant<'d> = marker::PhantomData<(fn(&'d ()) -> &'d (), rc::Rc<()>)>;

const INDEX_BITS: u32 = route::SLOT_BITS;
const GENERATION_BITS: u32 = 32;
type InnerArena = narrow::Arena<route::Token, INDEX_BITS, GENERATION_BITS>;
type InnerEcho = narrow::Echo<route::Token, INDEX_BITS, GENERATION_BITS>;
type InnerSlots<'d> = narrow::Slots<'d, route::Token, INDEX_BITS, GENERATION_BITS>;
type InnerReservation<'d> = narrow::Reservation<'d, route::Token, INDEX_BITS, GENERATION_BITS>;
type InnerLease<'d> = narrow::Lease<'d, route::Token, INDEX_BITS, GENERATION_BITS>;
type InnerResolved<'q> = narrow::Resolved<'q, route::Token, INDEX_BITS, GENERATION_BITS>;
type InnerDrain<'q> = narrow::Drain<'q, route::Token, INDEX_BITS, GENERATION_BITS>;

#[repr(transparent)]
pub(crate) struct Arena(InnerArena);

struct Owner<'a, 'd> {
    arena: &'a mut InnerArena,
    driver: driver::Reference<'d>,
}

#[doc(hidden)]
#[repr(transparent)]
pub struct Slots<'d, Tag: route::Tag> {
    slots: InnerSlots<'d>,
    driver: Invariant<'d>,
    tag: marker::PhantomData<Tag>,
}

#[must_use = "a reserved flight must be committed or released"]
#[repr(transparent)]
pub(crate) struct Reservation<'d> {
    reservation: InnerReservation<'d>,
    driver: Invariant<'d>,
}

#[must_use = "a live flight must reach terminal completion or quiescence"]
#[repr(transparent)]
pub struct Flight<'d> {
    flight: InnerLease<'d>,
    driver: Invariant<'d>,
}

#[repr(transparent)]
pub(crate) struct Completion<'q, 'd> {
    completion: InnerResolved<'q>,
    driver: Invariant<'d>,
}

pub(crate) struct Drain<'q, 'd> {
    drain: InnerDrain<'q>,
    driver: driver::Reference<'d>,
}

const _: () = {
    assert!(mem::size_of::<raw::Echo>() == mem::size_of::<usize>());
    assert!(mem::size_of::<Flight<'static>>() == mem::size_of::<usize>());
    assert!(mem::size_of::<Option<Flight<'static>>>() == mem::size_of::<usize>());
    assert!(mem::size_of::<Reservation<'static>>() == mem::size_of::<usize>());
    assert!(mem::size_of::<Completion<'static, 'static>>() == 2 * mem::size_of::<usize>());
    assert!(mem::size_of::<Drain<'static, 'static>>() == 2 * mem::size_of::<usize>());
    assert!(mem::size_of::<Slots<'static, route::KeyTag<1>>>() == mem::size_of::<usize>());
};

impl Arena {
    pub(crate) const fn new() -> Self {
        Self(InnerArena::new())
    }

    pub(crate) fn try_slots<'d, Tag: route::Tag>(
        &mut self,
        capacity: usize,
        driver: driver::Reference<'d>,
    ) -> io::Result<Slots<'d, Tag>> {
        Ok(Slots {
            slots: InnerArena::try_slots(
                Owner {
                    arena: &mut self.0,
                    driver,
                },
                capacity,
            )?,
            driver: marker::PhantomData,
            tag: marker::PhantomData,
        })
    }
}

impl<'d, Tag: route::Tag> Slots<'d, Tag> {
    pub(crate) fn reserve(&self, target: route::Operation<'d, Tag>) -> Option<Reservation<'d>> {
        if Tag::KIND != 0 && target.kind() != Tag::KIND {
            return None;
        }
        Some(Reservation {
            reservation: self.slots.reserve(target.into_token())?,
            driver: marker::PhantomData,
        })
    }
}

impl<'d> Reservation<'d> {
    pub(crate) fn key(&self) -> raw::Echo {
        raw::Echo::from_inner(self.reservation.key().echo())
    }

    pub(crate) fn commit(self) -> Flight<'d> {
        Flight {
            flight: self.reservation.commit(),
            driver: marker::PhantomData,
        }
    }
}

impl<'q, 'd> Drain<'q, 'd> {
    pub(in crate::driver) fn new(arena: &'q Arena, driver: driver::Reference<'d>) -> Self {
        Self {
            drain: arena.0.drain(),
            driver,
        }
    }

    pub(crate) fn driver(&self) -> driver::Reference<'d> {
        self.driver
    }

    pub(crate) fn complete(&self, key: raw::Echo) -> Option<Completion<'q, 'd>> {
        Some(Completion {
            completion: self.drain.complete(key.into_inner())?,
            driver: marker::PhantomData,
        })
    }
}

impl Completion<'_, '_> {
    pub(crate) fn resolve(self, more: bool) -> Option<route::Token> {
        self.completion.resolve(more)
    }
}

impl<'d> Flight<'d> {
    pub(crate) fn key(&self) -> raw::Echo {
        raw::Echo::from_inner(self.flight.key().echo())
    }

    pub fn target(&self) -> route::Token {
        self.flight.value()
    }

    pub(crate) fn target_erased(&self) -> route::Erased<'d> {
        route::Erased::new(self.target())
    }

    pub fn matches(&self, target: route::Token) -> bool {
        self.target() == target
    }

    pub fn complete(self) -> route::Token {
        self.flight.complete()
    }
}

impl fmt::Debug for Flight<'_> {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        formatter
            .debug_struct("Flight")
            .field("target", &self.target())
            .finish_non_exhaustive()
    }
}