1use netstack3_base::{Payload, SackBlocks, SeqNum};
10
11use arrayvec::ArrayVec;
12use core::fmt::Debug;
13use core::ops::Range;
14use packet::InnerPacketBuilder;
15
16use crate::internal::base::BufferSizes;
17use crate::internal::seq_ranges::{SeqRange, SeqRanges};
18
19pub trait Buffer: Debug + Sized {
21 fn limits(&self) -> BufferLimits;
26
27 fn target_capacity(&self) -> usize;
39
40 fn request_capacity(&mut self, size: usize);
46}
47
48pub trait ReceiveBuffer: Buffer {
50 fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize;
54
55 fn make_readable(&mut self, count: usize, has_outstanding: bool);
66}
67
68pub trait SendBuffer: Buffer {
70 type Payload<'a>: InnerPacketBuilder + Payload + Copy + Debug + 'a;
78
79 fn mark_read(&mut self, count: usize);
86
87 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
95 where
96 F: FnOnce(Self::Payload<'a>) -> R;
97}
98
99#[derive(Eq, PartialEq, Debug, Copy, Clone)]
101pub struct BufferLimits {
102 pub capacity: usize,
104
105 pub len: usize,
107}
108
109#[derive(Debug)]
111#[cfg_attr(test, derive(PartialEq, Eq))]
112pub(super) struct Assembler {
113 nxt: SeqNum,
117 generation: usize,
121 outstanding: SeqRanges<usize>,
126}
127
128impl Assembler {
129 pub(crate) const MAX_NUM_OUTSTANDING_RANGES: usize = 64;
135
136 pub(super) fn new(nxt: SeqNum) -> Self {
138 Self { outstanding: SeqRanges::default(), generation: 0, nxt }
139 }
140
141 pub(super) fn nxt(&self) -> SeqNum {
143 self.nxt
144 }
145
146 pub(super) fn has_out_of_order(&self) -> bool {
149 !self.outstanding.is_empty()
150 }
151
152 pub(super) fn insert(&mut self, Range { start, end }: Range<SeqNum>) -> usize {
164 assert!(!start.after(end));
165 assert!(!start.before(self.nxt));
166 if start == end {
167 return 0;
168 }
169
170 let Self { outstanding, nxt, generation } = self;
171 *generation = *generation + 1;
172 let _: bool = outstanding.insert(start..end, *generation);
173
174 if let Some(advanced) = outstanding.pop_front_if(|r| r.start() == *nxt) {
175 *nxt = advanced.end();
176 usize::try_from(advanced.len()).unwrap()
177 } else {
178 if outstanding.len() > Self::MAX_NUM_OUTSTANDING_RANGES {
181 let _evicted: Option<SeqRange<usize>> = outstanding.pop_back();
182 }
183 0
184 }
185 }
186
187 pub(super) fn has_outstanding(&self) -> bool {
188 let Self { outstanding, nxt: _, generation: _ } = self;
189 !outstanding.is_empty()
190 }
191
192 pub(crate) fn sack_blocks(&self, size_limits: SackBlockSizeLimiters) -> SackBlocks {
208 let Self { nxt: _, generation: _, outstanding } = self;
209 if outstanding.is_empty() {
211 return SackBlocks::default();
212 }
213
214 let mut heap = ArrayVec::<&SeqRange<_>, { SackBlocks::MAX_BLOCKS }>::new();
218 let num_blocks_allowed = size_limits.num_blocks_allowed();
219
220 for block in outstanding.iter() {
221 if heap.len() >= num_blocks_allowed {
222 if heap.last().is_some_and(|l| l.meta() < block.meta()) {
223 let _: Option<_> = heap.pop();
225 } else {
226 continue;
229 }
230 }
231
232 heap.push(block);
233 heap.sort_by(|a, b| b.meta().cmp(&a.meta()))
235 }
236
237 SackBlocks::from_iter(heap.into_iter().map(|block| block.to_sack_block()))
238 }
239}
240
241pub(crate) struct SackBlockSizeLimiters {
242 pub(crate) timestamp_enabled: bool,
243}
244
245impl SackBlockSizeLimiters {
246 fn num_blocks_allowed(&self) -> usize {
247 let Self { timestamp_enabled } = self;
248 if *timestamp_enabled {
249 SackBlocks::MAX_BLOCKS_WITH_TIMESTAMP
250 } else {
251 SackBlocks::MAX_BLOCKS
252 }
253 }
254}
255
256pub trait IntoBuffers<R: ReceiveBuffer, S: SendBuffer> {
259 fn into_buffers(self, buffer_sizes: BufferSizes) -> (R, S);
261}
262
263#[cfg(any(test, feature = "testutils"))]
264impl<R: Default + ReceiveBuffer, S: Default + SendBuffer> IntoBuffers<R, S> for () {
265 fn into_buffers(self, buffer_sizes: BufferSizes) -> (R, S) {
266 let BufferSizes { send: _, receive: _ } = buffer_sizes;
268 Default::default()
269 }
270}
271
272#[cfg(any(test, feature = "testutils"))]
273pub(crate) mod testutil {
274 use super::*;
275
276 use alloc::sync::Arc;
277 use alloc::vec;
278 use alloc::vec::Vec;
279 use core::cmp;
280
281 use either::Either;
282 use netstack3_base::{FragmentedPayload, PayloadLen, WindowSize};
283
284 use crate::internal::socket::accept_queue::{AcceptQueueChange, ListenerNotifier};
285
286 type Mutex<T> = netstack3_base::sync::Mutex<T, netstack3_base::sync::lock_impl::RawMutex>;
287
288 #[derive(Clone, PartialEq, Eq)]
305 pub struct RingBuffer {
306 pub(super) storage: Vec<u8>,
307 pub(super) head: usize,
312 pub(super) len: usize,
317 }
318
319 impl Debug for RingBuffer {
320 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
321 let Self { storage, head, len } = self;
322 f.debug_struct("RingBuffer")
323 .field("storage (len, cap)", &(storage.len(), storage.capacity()))
324 .field("head", head)
325 .field("len", len)
326 .finish()
327 }
328 }
329
330 impl Default for RingBuffer {
331 fn default() -> Self {
332 Self::new(WindowSize::DEFAULT.into())
333 }
334 }
335
336 impl RingBuffer {
337 pub fn new(capacity: usize) -> Self {
339 Self { storage: vec![0; capacity], head: 0, len: 0 }
340 }
341
342 pub fn reset(&mut self) {
344 let Self { storage: _, head, len } = self;
345 *head = 0;
346 *len = 0;
347 }
348
349 fn with_readable<'a, F, R>(storage: &'a Vec<u8>, start: usize, len: usize, f: F) -> R
351 where
352 F: for<'b> FnOnce(&'b [&'a [u8]]) -> R,
353 {
354 let end = start + len;
356 if end > storage.len() {
357 let first_part = &storage[start..storage.len()];
358 let second_part = &storage[0..len - first_part.len()];
359 f(&[first_part, second_part][..])
360 } else {
361 let all_bytes = &storage[start..end];
362 f(&[all_bytes][..])
363 }
364 }
365
366 pub fn read_with<F>(&mut self, f: F) -> usize
374 where
375 F: for<'a, 'b> FnOnce(&'b [&'a [u8]]) -> usize,
376 {
377 let Self { storage, head, len } = self;
378 if storage.len() == 0 {
379 return f(&[&[]]);
380 }
381 let nread = RingBuffer::with_readable(storage, *head, *len, f);
382 assert!(nread <= *len);
383 *len -= nread;
384 *head = (*head + nread) % storage.len();
385 nread
386 }
387
388 pub fn writable_regions(&mut self) -> impl IntoIterator<Item = &mut [u8]> {
390 let BufferLimits { capacity, len } = self.limits();
391 let available = capacity - len;
392 let Self { storage, head, len } = self;
393
394 let mut write_start = *head + *len;
395 if write_start >= storage.len() {
396 write_start -= storage.len()
397 }
398 let write_end = write_start + available;
399 if write_end <= storage.len() {
400 Either::Left([&mut self.storage[write_start..write_end]].into_iter())
401 } else {
402 let (b1, b2) = self.storage[..].split_at_mut(write_start);
403 let b2_len = b2.len();
404 Either::Right([b2, &mut b1[..(available - b2_len)]].into_iter())
405 }
406 }
407 }
408
409 impl Buffer for RingBuffer {
410 fn limits(&self) -> BufferLimits {
411 let Self { storage, len, head: _ } = self;
412 let capacity = storage.len();
413 BufferLimits { len: *len, capacity }
414 }
415
416 fn target_capacity(&self) -> usize {
417 let Self { storage, len: _, head: _ } = self;
418 storage.len()
419 }
420
421 fn request_capacity(&mut self, size: usize) {
422 unimplemented!("capacity request for {size} not supported")
423 }
424 }
425
426 impl ReceiveBuffer for RingBuffer {
427 fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize {
428 let BufferLimits { capacity, len } = self.limits();
429 let available = capacity - len;
430 let Self { storage, head, len } = self;
431 if storage.len() == 0 {
432 return 0;
433 }
434
435 if offset > available {
436 return 0;
437 }
438 let start_at = (*head + *len + offset) % storage.len();
439 let to_write = cmp::min(data.len(), available);
440 let first_len = cmp::min(to_write, storage.len() - start_at);
442 data.partial_copy(0, &mut storage[start_at..start_at + first_len]);
443 if to_write > first_len {
446 data.partial_copy(first_len, &mut storage[0..to_write - first_len]);
447 }
448 to_write
449 }
450
451 fn make_readable(&mut self, count: usize, _has_outstanding: bool) {
452 let BufferLimits { capacity, len } = self.limits();
453 debug_assert!(count <= capacity - len);
454 self.len += count;
455 }
456 }
457
458 impl SendBuffer for RingBuffer {
459 type Payload<'a> = FragmentedPayload<'a, 2>;
460
461 fn mark_read(&mut self, count: usize) {
462 let Self { storage, head, len } = self;
463 assert!(count <= *len);
464 *len -= count;
465 *head = (*head + count) % storage.len();
466 }
467
468 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
469 where
470 F: FnOnce(Self::Payload<'a>) -> R,
471 {
472 let Self { storage, head, len } = self;
473 if storage.len() == 0 {
474 return f(FragmentedPayload::new_empty());
475 }
476 assert!(offset <= *len);
477 RingBuffer::with_readable(
478 storage,
479 (*head + offset) % storage.len(),
480 *len - offset,
481 |readable| f(readable.iter().map(|x| *x).collect()),
482 )
483 }
484 }
485
486 impl RingBuffer {
487 pub(crate) fn enqueue_data(&mut self, data: &[u8]) -> usize {
491 let nwritten = self.write_at(0, &data);
492 self.make_readable(nwritten, false);
493 nwritten
494 }
495 }
496
497 impl Buffer for Arc<Mutex<RingBuffer>> {
498 fn limits(&self) -> BufferLimits {
499 self.lock().limits()
500 }
501
502 fn target_capacity(&self) -> usize {
503 self.lock().target_capacity()
504 }
505
506 fn request_capacity(&mut self, size: usize) {
507 self.lock().request_capacity(size)
508 }
509 }
510
511 impl ReceiveBuffer for Arc<Mutex<RingBuffer>> {
512 fn write_at<P: Payload>(&mut self, offset: usize, data: &P) -> usize {
513 self.lock().write_at(offset, data)
514 }
515
516 fn make_readable(&mut self, count: usize, has_outstanding: bool) {
517 self.lock().make_readable(count, has_outstanding)
518 }
519 }
520
521 #[derive(Debug, Default)]
523 pub struct TestSendBuffer {
524 fake_stream: Arc<Mutex<Vec<u8>>>,
525 ring: RingBuffer,
526 }
527
528 impl TestSendBuffer {
529 pub fn new(fake_stream: Arc<Mutex<Vec<u8>>>, ring: RingBuffer) -> TestSendBuffer {
532 Self { fake_stream, ring }
533 }
534
535 pub fn enqueue_data(&mut self, data: &[u8]) {
537 self.fake_stream.lock().extend_from_slice(data);
538 }
539 }
540
541 impl Buffer for TestSendBuffer {
542 fn limits(&self) -> BufferLimits {
543 let Self { fake_stream, ring } = self;
544 let BufferLimits { capacity: ring_capacity, len: ring_len } = ring.limits();
545 let guard = fake_stream.lock();
546 let len = ring_len + guard.len();
547 let capacity = ring_capacity + guard.capacity();
548 BufferLimits { len, capacity }
549 }
550
551 fn target_capacity(&self) -> usize {
552 let Self { fake_stream: _, ring } = self;
553 ring.target_capacity()
554 }
555
556 fn request_capacity(&mut self, size: usize) {
557 let Self { fake_stream: _, ring } = self;
558 ring.request_capacity(size)
559 }
560 }
561
562 impl SendBuffer for TestSendBuffer {
563 type Payload<'a> = FragmentedPayload<'a, 2>;
564
565 fn mark_read(&mut self, count: usize) {
566 let Self { fake_stream: _, ring } = self;
567 ring.mark_read(count)
568 }
569
570 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
571 where
572 F: FnOnce(Self::Payload<'a>) -> R,
573 {
574 let Self { fake_stream, ring } = self;
575 let mut guard = fake_stream.lock();
576 if !guard.is_empty() {
577 let BufferLimits { capacity, len } = ring.limits();
579 let len = (capacity - len).min(guard.len());
580 let rest = guard.split_off(len);
581 let first = core::mem::replace(&mut *guard, rest);
582 assert_eq!(ring.enqueue_data(&first[..]), len);
583 }
584 ring.peek_with(offset, f)
585 }
586 }
587
588 fn arc_mutex_eq<T: PartialEq>(a: &Arc<Mutex<T>>, b: &Arc<Mutex<T>>) -> bool {
589 if Arc::ptr_eq(a, b) {
590 return true;
591 }
592 (&*a.lock()) == (&*b.lock())
593 }
594
595 #[derive(Clone, Debug, Default)]
597 pub struct ClientBuffers {
598 pub receive: Arc<Mutex<RingBuffer>>,
600 pub send: Arc<Mutex<Vec<u8>>>,
602 }
603
604 impl PartialEq for ClientBuffers {
605 fn eq(&self, ClientBuffers { receive: other_receive, send: other_send }: &Self) -> bool {
606 let Self { receive, send } = self;
607 arc_mutex_eq(receive, other_receive) && arc_mutex_eq(send, other_send)
608 }
609 }
610
611 impl Eq for ClientBuffers {}
612
613 impl ClientBuffers {
614 pub fn new(buffer_sizes: BufferSizes) -> Self {
616 let BufferSizes { send, receive } = buffer_sizes;
617 Self {
618 receive: Arc::new(Mutex::new(RingBuffer::new(receive))),
619 send: Arc::new(Mutex::new(Vec::with_capacity(send))),
620 }
621 }
622 }
623
624 #[derive(Debug, Clone, Eq, PartialEq)]
626 #[allow(missing_docs)]
627 pub enum ProvidedBuffers {
628 Buffers(WriteBackClientBuffers),
629 NoBuffers,
630 }
631
632 impl Default for ProvidedBuffers {
633 fn default() -> Self {
634 Self::NoBuffers
635 }
636 }
637
638 impl From<WriteBackClientBuffers> for ProvidedBuffers {
639 fn from(buffers: WriteBackClientBuffers) -> Self {
640 ProvidedBuffers::Buffers(buffers)
641 }
642 }
643
644 impl From<ProvidedBuffers> for WriteBackClientBuffers {
645 fn from(extra: ProvidedBuffers) -> Self {
646 match extra {
647 ProvidedBuffers::Buffers(buffers) => buffers,
648 ProvidedBuffers::NoBuffers => Default::default(),
649 }
650 }
651 }
652
653 impl From<ProvidedBuffers> for () {
654 fn from(_: ProvidedBuffers) -> Self {
655 ()
656 }
657 }
658
659 impl From<()> for ProvidedBuffers {
660 fn from(_: ()) -> Self {
661 Default::default()
662 }
663 }
664
665 #[derive(Debug, Default, Clone)]
668 pub struct WriteBackClientBuffers(pub Arc<Mutex<Option<ClientBuffers>>>);
669
670 impl PartialEq for WriteBackClientBuffers {
671 fn eq(&self, Self(other): &Self) -> bool {
672 let Self(this) = self;
673 arc_mutex_eq(this, other)
674 }
675 }
676
677 impl Eq for WriteBackClientBuffers {}
678
679 impl IntoBuffers<Arc<Mutex<RingBuffer>>, TestSendBuffer> for ProvidedBuffers {
680 fn into_buffers(
681 self,
682 buffer_sizes: BufferSizes,
683 ) -> (Arc<Mutex<RingBuffer>>, TestSendBuffer) {
684 let buffers = ClientBuffers::new(buffer_sizes);
685 if let ProvidedBuffers::Buffers(b) = self {
686 *b.0.as_ref().lock() = Some(buffers.clone());
687 }
688 let ClientBuffers { receive, send } = buffers;
689 (receive, TestSendBuffer::new(send, Default::default()))
690 }
691 }
692
693 impl ListenerNotifier for ProvidedBuffers {
694 fn accept_queue_changed(&mut self, _: AcceptQueueChange) {}
695 }
696
697 #[derive(Clone, Copy, Debug)]
698 pub struct RepeatingPayload {
699 len: usize,
700 }
701
702 impl RepeatingPayload {
703 const REPEATING_BYTE: u8 = 0xAA;
704 }
705
706 impl PayloadLen for RepeatingPayload {
707 fn len(&self) -> usize {
708 self.len
709 }
710 }
711
712 impl Payload for RepeatingPayload {
713 fn slice(self, range: Range<u32>) -> Self {
714 Self { len: usize::try_from(range.end - range.start).unwrap() }
715 }
716
717 fn partial_copy(&self, offset: usize, dst: &mut [u8]) {
718 assert!(offset < self.len);
719 assert_eq!(dst.len() - offset, self.len);
720 dst.fill(Self::REPEATING_BYTE);
721 }
722
723 fn partial_copy_uninit(&self, offset: usize, dst: &mut [core::mem::MaybeUninit<u8>]) {
724 assert!(offset < self.len);
725 assert_eq!(dst.len() - offset, self.len);
726 dst.fill(core::mem::MaybeUninit::new(Self::REPEATING_BYTE));
727 }
728
729 fn new_empty() -> Self {
730 Self { len: 0 }
731 }
732 }
733
734 impl InnerPacketBuilder for RepeatingPayload {
735 fn bytes_len(&self) -> usize {
736 self.len
737 }
738
739 fn serialize(&self, buffer: &mut [u8]) {
740 buffer.fill(Self::REPEATING_BYTE)
741 }
742 }
743
744 #[derive(Default, Debug, Eq, PartialEq)]
746 pub struct InfiniteSendBuffer;
747
748 impl InfiniteSendBuffer {
749 const LEN: usize = usize::MAX as usize;
750 }
751
752 impl Buffer for InfiniteSendBuffer {
753 fn limits(&self) -> BufferLimits {
754 BufferLimits { capacity: Self::LEN, len: Self::LEN }
755 }
756
757 fn target_capacity(&self) -> usize {
758 Self::LEN
759 }
760
761 fn request_capacity(&mut self, size: usize) {
762 unimplemented!("can't change capacity of infinite send buffer to {size}")
763 }
764 }
765
766 impl SendBuffer for InfiniteSendBuffer {
767 type Payload<'a> = RepeatingPayload;
768
769 fn mark_read(&mut self, _count: usize) {}
770
771 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
772 where
773 F: FnOnce(Self::Payload<'a>) -> R,
774 {
775 f(RepeatingPayload { len: Self::LEN - offset })
776 }
777 }
778
779 #[derive(Default, Debug, Eq, PartialEq)]
782 pub struct RepeatingSendBuffer(usize);
783
784 impl RepeatingSendBuffer {
785 pub fn new(length: usize) -> Self {
787 Self(length)
788 }
789 }
790
791 impl Buffer for RepeatingSendBuffer {
792 fn limits(&self) -> BufferLimits {
793 let Self(len) = self;
794 BufferLimits { capacity: usize::MAX, len: *len }
795 }
796
797 fn target_capacity(&self) -> usize {
798 usize::MAX
799 }
800
801 fn request_capacity(&mut self, size: usize) {
802 unimplemented!("can't change capacity of repeatable send buffer to {size}")
803 }
804 }
805
806 impl SendBuffer for RepeatingSendBuffer {
807 type Payload<'a> = RepeatingPayload;
808
809 fn mark_read(&mut self, count: usize) {
810 let Self(len) = self;
811 *len = *len - count;
812 }
813
814 fn peek_with<'a, F, R>(&'a mut self, offset: usize, f: F) -> R
815 where
816 F: FnOnce(Self::Payload<'a>) -> R,
817 {
818 let Self(len) = self;
819 f(RepeatingPayload { len: *len - offset })
820 }
821 }
822}
823
824#[cfg(test)]
825mod test {
826 use alloc::vec;
827 use alloc::vec::Vec;
828
829 use netstack3_base::FragmentedPayload;
830 use proptest::strategy::{Just, Strategy};
831 use proptest::test_runner::Config;
832 use proptest::{prop_assert, prop_assert_eq, proptest};
833 use proptest_support::failed_seeds_no_std;
834 use test_case::test_case;
835 use testutil::RingBuffer;
836
837 use super::*;
838
839 fn contains_range(assembler: &Assembler, range: Range<SeqNum>) -> bool {
840 assembler.outstanding.iter().any(|r| r.start() == range.start && r.end() == range.end)
841 }
842
843 proptest! {
844 #![proptest_config(Config {
845 failure_persistence: failed_seeds_no_std!(
847 "cc f621ca7d3a2b108e0dc41f7169ad028f4329b79e90e73d5f68042519a9f63999",
848 "cc c449aebed201b4ec4f137f3c224f20325f4cfee0b7fd596d9285176b6d811aa9"
849 ),
850 ..Config::default()
851 })]
852
853 #[test]
854 fn ring_buffer_make_readable((mut rb, avail) in ring_buffer::with_written()) {
855 let old_storage = rb.storage.clone();
856 let old_head = rb.head;
857 let old_len = rb.limits().len;
858 rb.make_readable(avail, false);
859 let RingBuffer { storage, head, len } = rb;
861 prop_assert_eq!(len, old_len + avail);
862 prop_assert_eq!(head, old_head);
863 prop_assert_eq!(storage, old_storage);
864 }
865
866 #[test]
867 fn ring_buffer_write_at((mut rb, offset, data) in ring_buffer::with_offset_data()) {
868 let old_head = rb.head;
869 let old_len = rb.limits().len;
870 prop_assert_eq!(rb.write_at(offset, &&data[..]), data.len());
871 prop_assert_eq!(rb.head, old_head);
872 prop_assert_eq!(rb.limits().len, old_len);
873 for i in 0..data.len() {
874 let masked = (rb.head + rb.len + offset + i) % rb.storage.len();
875 prop_assert_eq!(rb.storage[masked], data[i]);
877 rb.storage[masked] = 0;
878 }
879 prop_assert_eq!(&rb.storage, &vec![0; rb.storage.len()]);
881 }
882
883 #[test]
884 fn ring_buffer_read_with((mut rb, expected, consume) in ring_buffer::with_read_data()) {
885 prop_assert_eq!(rb.limits().len, expected.len());
886 let nread = rb.read_with(|readable| {
887 assert!(readable.len() == 1 || readable.len() == 2);
888 let got = readable.concat();
889 assert_eq!(got, expected);
890 consume
891 });
892 prop_assert_eq!(nread, consume);
893 prop_assert_eq!(rb.limits().len, expected.len() - consume);
894 }
895
896 #[test]
897 fn ring_buffer_mark_read((mut rb, readable) in ring_buffer::with_readable()) {
898 const BYTE_TO_WRITE: u8 = 0x42;
899 let written = rb.writable_regions().into_iter().fold(0, |acc, slice| {
900 slice.fill(BYTE_TO_WRITE);
901 acc + slice.len()
902 });
903 let old_storage = rb.storage.clone();
904 let old_head = rb.head;
905 let old_len = rb.limits().len;
906
907 rb.mark_read(readable);
908 let new_writable = rb.writable_regions().into_iter().fold(Vec::new(), |mut acc, slice| {
909 acc.extend_from_slice(slice);
910 acc
911 });
912 for (i, x) in new_writable.iter().enumerate().take(written) {
913 prop_assert_eq!(*x, BYTE_TO_WRITE, "i={}, rb={:?}", i, rb);
914 }
915 prop_assert!(new_writable.len() >= written);
916
917 let RingBuffer { storage, head, len } = rb;
918 prop_assert_eq!(len, old_len - readable);
919 prop_assert_eq!(head, (old_head + readable) % old_storage.len());
920 prop_assert_eq!(storage, old_storage);
921 }
922
923 #[test]
924 fn ring_buffer_peek_with((mut rb, expected, offset) in ring_buffer::with_read_data()) {
925 prop_assert_eq!(rb.limits().len, expected.len());
926 rb.peek_with(offset, |readable| {
927 prop_assert_eq!(readable.to_vec(), &expected[offset..]);
928 Ok(())
929 })?;
930 prop_assert_eq!(rb.limits().len, expected.len());
931 }
932
933 #[test]
934 fn ring_buffer_writable_regions(mut rb in ring_buffer::arb_ring_buffer()) {
935 const BYTE_TO_WRITE: u8 = 0x42;
936 let writable_len = rb.writable_regions().into_iter().fold(0, |acc, slice| {
937 slice.fill(BYTE_TO_WRITE);
938 acc + slice.len()
939 });
940 let BufferLimits {len, capacity} = rb.limits();
941 prop_assert_eq!(writable_len + len, capacity);
942 for i in 0..capacity {
943 let expected = if i < len {
944 0
945 } else {
946 BYTE_TO_WRITE
947 };
948 let idx = (rb.head + i) % rb.storage.len();
949 prop_assert_eq!(rb.storage[idx], expected);
950 }
951 }
952 }
953
954 #[test_case([Range { start: 0, end: 0 }]
955 => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(0), generation: 0 })]
956 #[test_case([Range { start: 0, end: 10 }]
957 => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(10), generation: 1 })]
958 #[test_case([Range{ start: 10, end: 15 }, Range { start: 5, end: 10 }]
959 => Assembler {
960 outstanding: [
961 SeqRange::new(SeqNum::new(5)..SeqNum::new(15), 2).unwrap()
962 ].into_iter().collect(),
963 nxt: SeqNum::new(0),
964 generation: 2,
965 })
966 ]
967 #[test_case([Range{ start: 10, end: 15 }, Range { start: 0, end: 5 }, Range { start: 5, end: 10 }]
968 => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(15), generation: 3 })]
969 #[test_case([Range{ start: 10, end: 15 }, Range { start: 5, end: 10 }, Range { start: 0, end: 5 }]
970 => Assembler { outstanding: SeqRanges::default(), nxt: SeqNum::new(15), generation: 3 })]
971 #[test_case([Range{ start: 10, end: 15 }, Range { start: 10, end: 15 }, Range { start: 11, end: 12 }]
972 => Assembler {
973 outstanding: [
974 SeqRange::new(SeqNum::new(10)..SeqNum::new(15), 3).unwrap()
975 ].into_iter().collect(),
976 nxt: SeqNum::new(0), generation: 3 })]
977 fn assembler_examples(ops: impl IntoIterator<Item = Range<u32>>) -> Assembler {
978 let mut assembler = Assembler::new(SeqNum::new(0));
979 for Range { start, end } in ops.into_iter() {
980 let _advanced = assembler.insert(SeqNum::new(start)..SeqNum::new(end));
981 }
982 assembler
983 }
984
985 #[test_case(&[] => Vec::<Range<u32>>::new(); "empty")]
986 #[test_case(&[1..2] => vec![1..2]; "single")]
987 #[test_case(&[1..2, 3..4] => vec![3..4, 1..2]; "latest first")]
988 #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10]
989 => vec![9..10, 7..8, 5..6, 3..4]; "max len")]
990 #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10, 6..7]
991 => vec![5..8, 9..10, 3..4, 1..2]; "gap fill")]
992 #[test_case(&[1..2, 3..4, 5..6, 7..8, 9..10, 1..8]
993 => vec![1..8, 9..10]; "large gap fill")]
994 fn assembler_sack_blocks(ops: &[Range<u32>]) -> Vec<Range<u32>> {
995 let mut assembler = Assembler::new(SeqNum::new(0));
996 for Range { start, end } in ops {
997 let _: usize = assembler.insert(SeqNum::new(*start)..SeqNum::new(*end));
998 }
999 assembler
1000 .sack_blocks(SackBlockSizeLimiters { timestamp_enabled: false })
1001 .try_iter()
1002 .map(|r| r.expect("invalid block").into_range_u32())
1003 .collect()
1004 }
1005
1006 #[test_case(false => vec![10..11, 7..8, 4..5, 1..2]; "4_blocks_with_timestamp_disabled")]
1007 #[test_case(true => vec![10..11, 7..8, 4..5]; "3_blocks_with_timestamp_disabled")]
1008 fn assembler_sack_blocks_with_timestamp(timestamp_enabled: bool) -> Vec<Range<u32>> {
1009 let mut assembler = Assembler::new(SeqNum::new(0));
1010 for Range { start, end } in [1..2, 4..5, 7..8, 10..11] {
1011 let _: usize = assembler.insert(SeqNum::new(start)..SeqNum::new(end));
1012 }
1013 assembler
1014 .sack_blocks(SackBlockSizeLimiters { timestamp_enabled })
1015 .try_iter()
1016 .map(|r| r.expect("invalid_block").into_range_u32())
1017 .collect()
1018 }
1019
1020 #[test]
1022 fn assembler_max_outstanding_ranges() {
1023 const MAX: usize = Assembler::MAX_NUM_OUTSTANDING_RANGES;
1024
1025 const PERIOD: u32 = 20;
1027 const LEN: u32 = 10;
1028 const OFFSET: u32 = 10;
1029 let nth_range = |n| {
1030 SeqNum::new(PERIOD * (n as u32) + OFFSET)
1031 ..SeqNum::new(PERIOD * (n as u32) + OFFSET + LEN)
1032 };
1033
1034 let mut assembler = Assembler::new(SeqNum::new(0));
1036 for n in 0..MAX {
1037 assert_eq!(assembler.insert(nth_range(n)), 0);
1038 }
1039 assert_eq!(assembler.outstanding.len(), MAX);
1040 assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1041
1042 assert_eq!(assembler.insert(nth_range(MAX)), 0);
1044 assert_eq!(assembler.outstanding.len(), MAX);
1045 assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1046
1047 assert_eq!(assembler.insert(SeqNum::new(0)..SeqNum::new(1)), 1);
1050 assert_eq!(assembler.outstanding.len(), MAX);
1051 assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 1).start);
1052
1053 let middle_disjoint = SeqNum::new(PERIOD + 2)..SeqNum::new(PERIOD + OFFSET - 2);
1056 assert_eq!(assembler.insert(middle_disjoint.clone()), 0);
1057 assert_eq!(assembler.outstanding.len(), MAX);
1058 assert_eq!(assembler.outstanding.last().unwrap().start(), nth_range(MAX - 2).start);
1059 assert!(contains_range(&assembler, middle_disjoint));
1060
1061 let extending_range1 = nth_range(10).end..nth_range(10).end + 1;
1064 assert_eq!(assembler.insert(extending_range1.clone()), 0);
1065 assert_eq!(assembler.outstanding.len(), MAX);
1066 assert!(contains_range(&assembler, nth_range(10).start..extending_range1.end));
1067
1068 let extending_range2 = extending_range1.start..nth_range(11).start;
1071 assert_eq!(assembler.insert(extending_range2), 0);
1072 assert_eq!(assembler.outstanding.len(), MAX - 1);
1073 assert!(contains_range(&assembler, nth_range(10).start..nth_range(11).end));
1074 }
1075
1076 #[test]
1077 fn ring_buffer_wrap_around() {
1079 const CAPACITY: usize = 16;
1080 let mut rb = RingBuffer::new(CAPACITY);
1081
1082 const BUF_SIZE: usize = 10;
1084 assert_eq!(rb.enqueue_data(&[0xAA; BUF_SIZE]), BUF_SIZE);
1085 rb.peek_with(0, |payload| {
1086 assert_eq!(payload, FragmentedPayload::new_contiguous(&[0xAA; BUF_SIZE]))
1087 });
1088 rb.mark_read(BUF_SIZE);
1089
1090 assert_eq!(rb.enqueue_data(&[0xBB; BUF_SIZE]), BUF_SIZE);
1092 rb.peek_with(0, |payload| {
1093 assert_eq!(
1094 payload,
1095 FragmentedPayload::new([
1096 &[0xBB; (CAPACITY - BUF_SIZE)],
1097 &[0xBB; (BUF_SIZE * 2 - CAPACITY)]
1098 ])
1099 )
1100 });
1101 rb.mark_read(BUF_SIZE);
1104
1105 assert_eq!(rb.enqueue_data(&[0xCC; BUF_SIZE]), BUF_SIZE);
1107 rb.peek_with(0, |payload| {
1108 assert_eq!(payload, FragmentedPayload::new_contiguous(&[0xCC; BUF_SIZE]))
1109 });
1110
1111 let read = rb.read_with(|segments| {
1114 assert_eq!(segments, [[0xCC; BUF_SIZE]]);
1115 BUF_SIZE
1116 });
1117 assert_eq!(read, BUF_SIZE);
1118 }
1119
1120 #[test]
1121 fn ring_buffer_example() {
1122 let mut rb = RingBuffer::new(16);
1123 assert_eq!(rb.write_at(5, &"World".as_bytes()), 5);
1124 assert_eq!(rb.write_at(0, &"Hello".as_bytes()), 5);
1125 rb.make_readable(10, false);
1126 assert_eq!(
1127 rb.read_with(|readable| {
1128 assert_eq!(readable, &["HelloWorld".as_bytes()]);
1129 5
1130 }),
1131 5
1132 );
1133 assert_eq!(
1134 rb.read_with(|readable| {
1135 assert_eq!(readable, &["World".as_bytes()]);
1136 readable[0].len()
1137 }),
1138 5
1139 );
1140 assert_eq!(rb.write_at(0, &"HelloWorld".as_bytes()), 10);
1141 rb.make_readable(10, false);
1142 assert_eq!(
1143 rb.read_with(|readable| {
1144 assert_eq!(readable, &["HelloW".as_bytes(), "orld".as_bytes()]);
1145 6
1146 }),
1147 6
1148 );
1149 assert_eq!(rb.limits().len, 4);
1150 assert_eq!(
1151 rb.read_with(|readable| {
1152 assert_eq!(readable, &["orld".as_bytes()]);
1153 4
1154 }),
1155 4
1156 );
1157 assert_eq!(rb.limits().len, 0);
1158
1159 assert_eq!(rb.enqueue_data("Hello".as_bytes()), 5);
1160 assert_eq!(rb.limits().len, 5);
1161
1162 rb.peek_with(3, |readable| {
1163 assert_eq!(readable.to_vec(), "lo".as_bytes());
1164 });
1165
1166 rb.mark_read(2);
1167
1168 rb.peek_with(0, |readable| {
1169 assert_eq!(readable.to_vec(), "llo".as_bytes());
1170 });
1171 }
1172
1173 mod ring_buffer {
1174 use super::*;
1175 const MAX_CAP: usize = 32;
1178
1179 fn arb_ring_buffer_args() -> impl Strategy<Value = (usize, usize, usize)> {
1180 (1..=MAX_CAP).prop_flat_map(|cap| {
1183 let max_len = cap;
1184 (Just(cap), 0..cap, 0..=max_len)
1186 })
1187 }
1188
1189 pub(super) fn arb_ring_buffer() -> impl Strategy<Value = RingBuffer> {
1190 arb_ring_buffer_args().prop_map(|(cap, head, len)| RingBuffer {
1191 storage: vec![0; cap],
1192 head,
1193 len,
1194 })
1195 }
1196
1197 pub(super) fn with_readable() -> impl Strategy<Value = (RingBuffer, usize)> {
1199 arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1200 (Just(RingBuffer { storage: vec![0; cap], head, len }), 0..=len)
1201 })
1202 }
1203
1204 pub(super) fn with_written() -> impl Strategy<Value = (RingBuffer, usize)> {
1206 arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1207 let rb = RingBuffer { storage: vec![0; cap], head, len };
1208 let max_written = cap - len;
1209 (Just(rb), 0..=max_written)
1210 })
1211 }
1212
1213 pub(super) fn with_offset_data() -> impl Strategy<Value = (RingBuffer, usize, Vec<u8>)> {
1215 arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1216 let writable_len = cap - len;
1217 (0..=writable_len).prop_flat_map(move |offset| {
1218 (0..=writable_len - offset).prop_flat_map(move |data_len| {
1219 (
1220 Just(RingBuffer { storage: vec![0; cap], head, len }),
1221 Just(offset),
1222 proptest::collection::vec(1..=u8::MAX, data_len),
1223 )
1224 })
1225 })
1226 })
1227 }
1228
1229 pub(super) fn with_read_data() -> impl Strategy<Value = (RingBuffer, Vec<u8>, usize)> {
1232 arb_ring_buffer_args().prop_flat_map(|(cap, head, len)| {
1233 proptest::collection::vec(1..=u8::MAX, len).prop_flat_map(move |data| {
1234 let mut rb = RingBuffer { storage: vec![0; cap], head, len: 0 };
1236 assert_eq!(rb.write_at(0, &&data[..]), len);
1237 rb.make_readable(len, false);
1238 (Just(rb), Just(data), 0..=len)
1239 })
1240 })
1241 }
1242 }
1243}