#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[cfg(feature = "serde")]
use serde_big_array::BigArray;
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(
feature = "serde",
serde(
bound = "EntryType: serde::Serialize + serde::de::DeserializeOwned, RestType: serde::Serialize + serde::de::DeserializeOwned"
)
)]
#[derive(Clone)]
pub struct WheelEntry<EntryType, RestType> {
pub entry: EntryType,
pub rest: RestType,
}
pub type WheelEntryList<EntryType, RestType> = Vec<WheelEntry<EntryType, RestType>>;
const NUM_SLOTS: usize = 256;
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(
feature = "serde",
serde(
bound = "EntryType: serde::Serialize + serde::de::DeserializeOwned, RestType: serde::Serialize + serde::de::DeserializeOwned"
)
)]
pub struct ByteWheel<EntryType, RestType> {
#[cfg_attr(feature = "serde", serde(with = "BigArray"))]
slots: [Option<WheelEntryList<EntryType, RestType>>; NUM_SLOTS],
count: u64,
current: u8,
}
impl<EntryType, RestType> ByteWheel<EntryType, RestType> {
const INIT_VALUE: Option<WheelEntryList<EntryType, RestType>> = None;
pub fn new() -> Self {
let slots: [Option<WheelEntryList<EntryType, RestType>>; NUM_SLOTS] =
[Self::INIT_VALUE; NUM_SLOTS];
ByteWheel {
slots,
count: 0,
current: 0,
}
}
pub fn current(&self) -> u8 {
self.current
}
pub fn advance(&mut self, to: u8) {
self.current = to;
}
pub fn insert(&mut self, pos: u8, e: EntryType, r: RestType) {
let index = pos as usize;
let we = WheelEntry { entry: e, rest: r };
if self.slots[index].is_none() {
let l = Vec::new();
let bl = Some(l);
self.slots[index] = bl;
}
if let Some(l) = &mut self.slots[index] {
l.push(we);
self.count += 1;
}
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
pub fn tick(&mut self) -> (Option<WheelEntryList<EntryType, RestType>>, u8) {
self.current = self.current.wrapping_add(1u8);
let index = self.current as usize;
let cur = self.slots[index].take(); if let Some(ref l) = cur {
self.count -= l.len() as u64;
}
(cur, self.current)
}
}
impl<EntryType, RestType> Default for ByteWheel<EntryType, RestType> {
fn default() -> Self {
Self::new()
}
}