use core::ops::{Deref, DerefMut};
use smallvec::{smallvec, SmallVec};
use super::PollState;
const MAX_INLINE_ENTRIES: usize = core::mem::size_of::<usize>() * 3 - 2;
#[derive(Default)]
pub(crate) struct PollVec(SmallVec<[PollState; MAX_INLINE_ENTRIES]>);
impl PollVec {
pub(crate) fn new(len: usize) -> Self {
Self(smallvec![PollState::None; len])
}
pub(crate) fn new_pending(len: usize) -> Self {
Self(smallvec![PollState::Pending; len])
}
pub(crate) fn ready_indexes(&self) -> impl Iterator<Item = usize> + '_ {
self.iter()
.cloned()
.enumerate()
.filter(|(_, state)| state.is_ready())
.map(|(i, _)| i)
}
#[allow(unused)]
pub(crate) fn pending_indexes(&self) -> impl Iterator<Item = usize> + '_ {
self.iter()
.cloned()
.enumerate()
.filter(|(_, state)| state.is_pending())
.map(|(i, _)| i)
}
#[allow(unused)]
pub(crate) fn consumed_indexes(&self) -> impl Iterator<Item = usize> + '_ {
self.iter()
.cloned()
.enumerate()
.filter(|(_, state)| state.is_none())
.map(|(i, _)| i)
}
#[inline]
pub(crate) fn set_all_pending(&mut self) {
self.0.fill(PollState::Pending);
}
#[inline]
#[allow(unused)]
pub(crate) fn set_all_none(&mut self) {
self.0.fill(PollState::None);
}
pub(crate) fn resize(&mut self, len: usize) {
self.0.resize_with(len, || PollState::None)
}
}
impl Deref for PollVec {
type Target = [PollState];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for PollVec {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[cfg(test)]
mod tests {
use super::{PollVec, MAX_INLINE_ENTRIES};
#[test]
fn type_size() {
assert_eq!(
core::mem::size_of::<PollVec>(),
core::mem::size_of::<usize>() * 4
);
}
#[test]
fn boxed_does_not_allocate_twice() {
let _ = PollVec::new_pending(MAX_INLINE_ENTRIES + 10);
}
}