mod failover;
mod gear;
mod slot;
mod wheel;
use std::{convert::Infallible, time::Instant};
pub use failover::*;
pub use wheel::*;
pub use crate::timer::gear::InsertError;
pub trait Timer {
type Context;
fn fire(&mut self, ctx: &mut Self::Context);
}
pub trait TimerDriver<T: Timer>: Default {
type Err;
fn insert(&mut self, when: Instant, timer: T) -> Result<TimerHandle, Self::Err>;
fn remove(&mut self, handle: TimerHandle) -> Option<T>;
fn poll(&mut self, now: Instant, ctx: &mut T::Context) -> usize;
fn peek_next_fire(&self) -> Option<Instant>;
fn len(&self) -> usize;
fn cancel(&mut self, handle: TimerHandle) -> bool {
self.remove(handle).is_some()
}
fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<T, const G: usize, const R: u64, const S: usize, const P: usize> TimerDriver<T>
for BitWheel<T, G, R, S, P>
where
T: Timer,
{
type Err = InsertError<T>;
#[inline(always)]
fn insert(&mut self, when: Instant, timer: T) -> Result<TimerHandle, Self::Err> {
BitWheel::insert(self, when, timer)
}
#[inline(always)]
fn remove(&mut self, handle: TimerHandle) -> Option<T> {
BitWheel::cancel(self, handle)
}
#[inline(always)]
fn poll(&mut self, now: Instant, ctx: &mut T::Context) -> usize {
BitWheel::poll(self, now, ctx)
}
#[inline(always)]
fn peek_next_fire(&self) -> Option<Instant> {
BitWheel::peek_next_fire(self)
}
#[inline(always)]
fn len(&self) -> usize {
BitWheel::len(self)
}
}
impl<T, const G: usize, const R: u64, const S: usize, const P: usize, const F: u64> TimerDriver<T>
for BitWheelWithFailover<T, G, R, S, P, F>
where
T: Timer,
{
type Err = Infallible;
#[inline(always)]
fn insert(&mut self, when: Instant, timer: T) -> Result<TimerHandle, Self::Err> {
Ok(BitWheelWithFailover::insert(self, when, timer))
}
#[inline(always)]
fn remove(&mut self, handle: TimerHandle) -> Option<T> {
BitWheelWithFailover::cancel(self, handle)
}
#[inline(always)]
fn poll(&mut self, now: Instant, ctx: &mut T::Context) -> usize {
BitWheelWithFailover::poll(self, now, ctx)
}
#[inline(always)]
fn peek_next_fire(&self) -> Option<Instant> {
BitWheelWithFailover::peek_next_fire(self)
}
#[inline(always)]
fn len(&self) -> usize {
BitWheelWithFailover::len(self)
}
}
#[derive(Debug, PartialEq, Eq, Hash)]
#[repr(C, align(16))]
pub struct TimerHandle {
when_offset: u64,
key: u32,
gear: u8,
slot: u8,
overflow: bool,
}
pub type Wheel<T> = BitWheel<T, 2, 4, 32, 8>;
pub type SmallWheel<T> = BitWheel<T, 2, 4, 16, 16>;
pub type LargeWheel<T> = BitWheel<T, 2, 4, 128, 2>;
pub type PreciseWheel<T> = BitWheel<T, 3, 1, 32, 8>;
pub type SmallPreciseWheel<T> = BitWheel<T, 3, 1, 16, 16>;
pub type LargePreciseWheel<T> = BitWheel<T, 3, 1, 128, 2>;
pub type BurstWheel<T> = BitWheel<T, 2, 4, 64, 8>;
pub type SmallBurstWheel<T> = BitWheel<T, 2, 4, 32, 16>;
pub type LargeBurstWheel<T> = BitWheel<T, 2, 4, 256, 2>;
pub type WheelWithFailover<T> = BitWheelWithFailover<T, 2, 4, 32, 8, 32>;
pub type SmallWheelWithFailover<T> = BitWheelWithFailover<T, 2, 4, 16, 16, 32>;
pub type LargeWheelWithFailover<T> = BitWheelWithFailover<T, 2, 4, 128, 2, 32>;
pub type PreciseWheelWithFailover<T> = BitWheelWithFailover<T, 3, 1, 32, 8, 32>;
pub type SmallPreciseWheelWithFailover<T> = BitWheelWithFailover<T, 3, 1, 16, 16, 32>;
pub type LargePreciseWheelWithFailover<T> = BitWheelWithFailover<T, 3, 1, 128, 2, 32>;
pub type BurstWheelWithFailover<T> = BitWheelWithFailover<T, 2, 4, 64, 8, 32>;
pub type SmallBurstWheelWithFailover<T> = BitWheelWithFailover<T, 2, 4, 32, 16, 32>;
pub type LargeBurstWheelWithFailover<T> = BitWheelWithFailover<T, 2, 4, 256, 2, 32>;
#[macro_export]
macro_rules! define_bitwheel {
($name:ident, $timer:ty, $num_gears:expr, $resolution_ms:expr, $slot_cap:expr, $max_probes:expr) => {
pub type $name =
$crate::BitWheel<$timer, $num_gears, $resolution_ms, $slot_cap, $max_probes>;
};
}