impl<T: Sized> RingBuffer<T> { /// Creates a new instance of a ring buffer. pubfn new(capacity: usize) -> Self { letmut data = Vec::new();
data.resize_with(capacity + 1, MaybeUninit::uninit); Self {
data: SharedVec::new(data),
head: CachePadded::new(AtomicUsize::new(0)),
tail: CachePadded::new(AtomicUsize::new(0)),
}
}
/// Splits ring buffer into producer and consumer. pubfn split(self) -> (Producer<T>, Consumer<T>) { let arc = Arc::new(self);
(Producer { rb: arc.clone() }, Consumer { rb: arc })
}
/// Returns capacity of the ring buffer. pubfn capacity(&self) -> usize { self.data.len() - 1
}
/// Checks if the ring buffer is empty. pubfn is_empty(&self) -> bool { let head = self.head.load(Ordering::Acquire); let tail = self.tail.load(Ordering::Acquire);
head == tail
}
/// Checks if the ring buffer is full. pubfn is_full(&self) -> bool { let head = self.head.load(Ordering::Acquire); let tail = self.tail.load(Ordering::Acquire);
(tail + 1) % self.data.len() == head
}
/// The length of the data in the buffer. pubfn len(&self) -> usize { let head = self.head.load(Ordering::Acquire); let tail = self.tail.load(Ordering::Acquire);
(tail + self.data.len() - head) % self.data.len()
}
/// The remaining space in the buffer. pubfn remaining(&self) -> usize { self.capacity() - self.len()
}
}
impl<T: Sized> Drop for RingBuffer<T> { fn drop(&mutself) { let data = unsafe { self.data.get_mut() };
let head = self.head.load(Ordering::Acquire); let tail = self.tail.load(Ordering::Acquire); let len = data.len();
let slices = if head <= tail {
(head..tail, 0..0)
} else {
(head..len, 0..tail)
};
let drop = |elem_ref: &mut MaybeUninit<T>| unsafe {
elem_ref.as_ptr().read();
}; for elem in data[slices.0].iter_mut() {
drop(elem);
} for elem in data[slices.1].iter_mut() {
drop(elem);
}
}
}
/// Moves at most `count` items from the `src` consumer to the `dst` producer. /// Consumer and producer may be of different buffers as well as of the same one. /// /// `count` is the number of items being moved, if `None` - as much as possible items will be moved. /// /// Returns number of items been moved. pubfn move_items<T>(src: &mut Consumer<T>, dst: &mut Producer<T>, count: Option<usize>) -> usize { unsafe {
src.pop_access(|src_left, src_right| -> usize {
dst.push_access(|dst_left, dst_right| -> usize { let n = count.unwrap_or_else(|| {
min(
src_left.len() + src_right.len(),
dst_left.len() + dst_right.len(),
)
}); letmut m = 0; letmut src = (SlicePtr::new(src_left), SlicePtr::new(src_right)); letmut dst = (SlicePtr::new(dst_left), SlicePtr::new(dst_right));
loop { let k = min(n - m, min(src.0.len, dst.0.len)); if k == 0 { break;
}
copy(src.0.ptr, dst.0.ptr, k); if src.0.len == k {
src.0 = src.1;
src.1 = SlicePtr::null();
} else {
src.0.shift(k);
} if dst.0.len == k {
dst.0 = dst.1;
dst.1 = SlicePtr::null();
} else {
dst.0.shift(k);
}
m += k
}
m
})
})
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-19)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.