pub struct OrderedQueue<T> { /* private fields */ }Expand description
A reorder buffer that outputs items in serial order.
Uses smart backpressure to prevent deadlock:
- When waiting for
next_seq: MUST accept items (refusing would deadlock) - When we have
next_seq: CAN refuse items (consumer can drain)
§Deadlock Prevention
The key insight is that if we’re waiting for serial N, we must accept serials N+1, N+2, etc. because serial N might be produced by another thread that’s blocked trying to push to this queue. Only when we have serial N available can we safely apply backpressure, because the consumer can make progress by draining serial N.
§Example
let queue = OrderedQueue::new(1_000_000); // 1MB limit
queue.insert(2, item2, 1000)?; // Accepted (waiting for 0)
queue.insert(0, item0, 1000)?; // Accepted (now has 0)
let (item, size) = queue.try_pop_next().unwrap(); // Returns item0
queue.insert(1, item1, 1000)?; // Accepted (now has 1)Implementations§
Source§impl<T> OrderedQueue<T>
impl<T> OrderedQueue<T>
Sourcepub fn can_accept(&self, heap_size: usize) -> bool
pub fn can_accept(&self, heap_size: usize) -> bool
Check if we can accept an item (lock-free fast path).
Returns true if:
- We don’t have
next_seq(must accept to make progress), OR - We’re under the memory limit
Sourcepub fn insert(
&self,
serial: u64,
item: T,
heap_size: usize,
) -> Result<(), (T, usize)>
pub fn insert( &self, serial: u64, item: T, heap_size: usize, ) -> Result<(), (T, usize)>
Insert an item into the reorder buffer.
Acceptance rule:
- If we do NOT have
next_seq: ACCEPT (must accumulate for progress) - If we DO have
next_seq: only accept if under memory limit
Returns Err((item, heap_size)) if rejected due to backpressure.
§Errors
Returns the item and heap size if rejected due to memory backpressure.
Sourcepub fn try_pop_next(&self) -> Option<(T, usize)>
pub fn try_pop_next(&self) -> Option<(T, usize)>
Try to pop the next item in serial order.
Returns Some((item, heap_size)) if next_seq is available.
Sourcepub fn current_bytes(&self) -> u64
pub fn current_bytes(&self) -> u64
Current memory usage in bytes.
Sourcepub fn limit_bytes(&self) -> u64
pub fn limit_bytes(&self) -> u64
Get current limit.
Sourcepub fn record_sample(&self)
pub fn record_sample(&self)
Record a sample for stats.
Sourcepub fn record_blocked(&self, ns: u64)
pub fn record_blocked(&self, ns: u64)
Record blocked time in nanoseconds.
Sourcepub fn collect_stats(&self) -> QueueStats
pub fn collect_stats(&self) -> QueueStats
Collect and reset stats.
Auto Trait Implementations§
impl<T> !Freeze for OrderedQueue<T>
impl<T> !RefUnwindSafe for OrderedQueue<T>
impl<T> Send for OrderedQueue<T>where
T: Send,
impl<T> Sync for OrderedQueue<T>where
T: Send,
impl<T> Unpin for OrderedQueue<T>where
T: Unpin,
impl<T> UnsafeUnpin for OrderedQueue<T>
impl<T> UnwindSafe for OrderedQueue<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more