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