use core::cmp::Reverse;
use intrusive_collections::KeyAdapter;
use crate::{
calendar::{IdleOnDrop, Scheduler, ordering::ForceOrd},
config::Config,
continuation::{Adapter, Continuation},
fsm::Brand,
simulator::{Mark, Prec},
};
pub(super) struct TimeKey<C: ?Sized + Config>(pub Adapter<C, IdleOnDrop<C>>);
pub(super) struct RankKey<C: ?Sized + Config>(pub Adapter<C, IdleOnDrop<C>>);
crate::intrusive_adapter_newtype!(TimeKey, RankKey);
impl<'a, C: ?Sized + Config> KeyAdapter<'a> for TimeKey<C>
where
C::Plan: Scheduler<State = super::State<C>>,
{
type Key = ForceOrd<C::Time>;
#[inline]
fn get_key(&self, cont: &'a Continuation<'static, C>) -> Self::Key {
cont.brand(|inner, once| {
let next = match inner.token(once).into_next() {
Ok(next) => next,
#[cfg(debug_assertions)]
Err(err) => panic!("{}", err),
#[cfg(not(debug_assertions))]
_ => unsafe { core::hint::unreachable_unchecked() },
};
inner.next_state(&next, |s| ForceOrd(s.time))
})
}
}
impl<'a, C: ?Sized + Config> KeyAdapter<'a> for RankKey<C>
where
C::Plan: Scheduler<State = super::State<C>>,
{
type Key = (
Reverse<C::Rank>, Mark, Prec, u64, );
#[inline]
fn get_key(&self, cont: &'a Continuation<'static, C>) -> Self::Key {
cont.brand(|inner, once| {
let next = match inner.token(once).into_next() {
Ok(next) => next,
#[cfg(debug_assertions)]
Err(err) => panic!("{}", err),
#[cfg(not(debug_assertions))]
_ => unsafe { core::hint::unreachable_unchecked() },
};
inner.next_state(&next, |s| {
(
Reverse(inner.branded_share(&next).rank()),
inner.mark(&next).get(),
inner.prec(),
s.count,
)
})
})
}
}