use std::sync::Arc; use crossbeam_queue::{ArrayQueue, SegQueue}; pub struct HybridChannel { ring: ArrayQueue, overflow: SegQueue, } impl HybridChannel { pub fn new(capacity: usize) -> Self { Self { ring: ArrayQueue::new(capacity), overflow: SegQueue::new(), } } pub fn push(&self, value: T) { if !self.overflow.is_empty() { self.overflow.push(value); return; } if let Err(v) = self.ring.push(value) { self.overflow.push(v); } } pub fn pop(&self) -> Option { self.ring.pop().or_else(|| self.overflow.pop()) } } pub(crate) struct Receiver { queue: Arc>, } impl Receiver { pub fn new(capacity: usize) -> Self { let queue = Arc::new(HybridChannel::new(capacity)); Self { queue } } pub fn try_recv(&self) -> Option { self.queue.pop() } pub fn new_sender(&self) -> Sender { Sender { queue: self.queue.clone(), } } } pub(crate) struct Sender { queue: Arc>, } impl Sender { pub fn send(&self, value: T) { self.queue.push(value) } }