use crate::{MpscQueue, PopResult};
pub struct BatchMpscQueue<T> {
inner: MpscQueue<T>,
}
impl<T> BatchMpscQueue<T> {
pub fn new() -> Self {
Self {
inner: MpscQueue::new(),
}
}
pub fn push(&self, value: T) {
self.inner.push(value);
}
pub fn push_batch<I: IntoIterator<Item = T>>(&self, values: I) -> usize {
self.inner.push_batch(values)
}
pub fn try_dequeue_batch(&mut self, out: &mut [Option<T>]) -> usize {
let mut n = 0;
while n < out.len() {
match self.inner.try_pop() {
PopResult::Some(v) => {
out[n] = Some(v);
n += 1;
}
PopResult::Empty | PopResult::Inconsistent => break,
}
}
n
}
pub fn drain<F: FnMut(T)>(&mut self, limit: usize, mut f: F) -> usize {
let mut n = 0;
while n < limit {
match self.inner.try_pop() {
PopResult::Some(v) => {
f(v);
n += 1;
}
PopResult::Empty | PopResult::Inconsistent => break,
}
}
n
}
pub fn drain_into_vec(&mut self, out: &mut Vec<T>, cap: usize) -> usize {
let mut n = 0;
while n < cap {
match self.inner.try_pop() {
PopResult::Some(v) => {
out.push(v);
n += 1;
}
PopResult::Empty | PopResult::Inconsistent => break,
}
}
n
}
pub fn peek(&mut self) -> Option<&T> {
self.inner.peek()
}
pub fn is_empty(&mut self) -> bool {
self.inner.is_empty()
}
pub fn len(&mut self) -> usize {
self.inner.len()
}
pub fn clear(&mut self) -> usize {
self.inner.clear()
}
}
impl<T> Default for BatchMpscQueue<T> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
#[path = "batch_tests.rs"]
mod tests;