Skip to content

Commit

Permalink
feat(s2n-quic-core): add buffer reader/writer traits (#2097)
Browse files Browse the repository at this point in the history
  • Loading branch information
camshaft authored Feb 8, 2024
1 parent 7152a0c commit 03f97ad
Show file tree
Hide file tree
Showing 46 changed files with 3,918 additions and 210 deletions.
42 changes: 12 additions & 30 deletions quic/s2n-quic-bench/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// SPDX-License-Identifier: Apache-2.0

use criterion::{black_box, BenchmarkId, Criterion, Throughput};
use s2n_quic_core::{buffer::ReceiveBuffer, varint::VarInt};
use s2n_quic_core::{
buffer::{reader::Storage as _, writer, Reassembler},
varint::VarInt,
};

pub fn benchmarks(c: &mut Criterion) {
let mut group = c.benchmark_group("buffer");
Expand All @@ -13,19 +16,21 @@ pub fn benchmarks(c: &mut Criterion) {
group.throughput(Throughput::Bytes(input.len() as _));

group.bench_with_input(BenchmarkId::new("skip", size), &input, |b, _input| {
let mut buffer = ReceiveBuffer::new();
let mut buffer = Reassembler::new();
let size = VarInt::try_from(size).unwrap();
b.iter(move || {
buffer.skip(black_box(size)).unwrap();
});
});

group.bench_with_input(BenchmarkId::new("write_at", size), &input, |b, input| {
let mut buffer = ReceiveBuffer::new();
let mut buffer = Reassembler::new();
let mut offset = VarInt::from_u8(0);
let len = VarInt::new(input.len() as _).unwrap();
b.iter(move || {
buffer.write_at(offset, input).unwrap();
buffer.copy_into_buf(&mut NoOpBuf);
// Avoid oversampling the `pop` implementation
buffer.copy_into(&mut writer::storage::Discard).unwrap();
offset += len;
});
});
Expand All @@ -36,42 +41,19 @@ pub fn benchmarks(c: &mut Criterion) {
BenchmarkId::new("write_at_fragmented", size),
&input,
|b, input| {
let mut buffer = ReceiveBuffer::new();
let mut buffer = Reassembler::new();
let mut offset = VarInt::from_u8(0);
let len = VarInt::new(input.len() as _).unwrap();
b.iter(move || {
let first_offset = offset + len;
buffer.write_at(first_offset, input).unwrap();
let second_offset = offset;
buffer.write_at(second_offset, input).unwrap();
buffer.copy_into_buf(&mut NoOpBuf);
// Avoid oversampling the `pop` implementation
buffer.copy_into(&mut writer::storage::Discard).unwrap();
offset = first_offset + len;
});
},
);
}
}

/// A BufMut implementation that doesn't actually copy data into it
///
/// This is used to avoid oversampling the `pop` implementation for
/// `write_at` benchmarks.
struct NoOpBuf;

unsafe impl bytes::BufMut for NoOpBuf {
#[inline]
fn remaining_mut(&self) -> usize {
usize::MAX
}

#[inline]
unsafe fn advance_mut(&mut self, _cnt: usize) {}

#[inline]
fn put_slice(&mut self, _slice: &[u8]) {}

#[inline]
fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
unimplemented!()
}
}
14 changes: 14 additions & 0 deletions quic/s2n-quic-core/src/buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

pub mod duplex;
mod error;
pub mod reader;
pub mod reassembler;
pub mod writer;

pub use duplex::Duplex;
pub use error::Error;
pub use reader::Reader;
pub use reassembler::Reassembler;
pub use writer::Writer;
23 changes: 23 additions & 0 deletions quic/s2n-quic-core/src/buffer/duplex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use super::{Error, Reader, Writer};
use crate::varint::VarInt;

mod interposer;

pub use interposer::Interposer;

/// A buffer that is capable of both reading and writing
pub trait Duplex: Reader + Writer {}

impl<T: Reader + Writer> Duplex for T {}

/// A buffer which can be advanced forward without reading or writing payloads. This
/// is essentially a forward-only [`std::io::Seek`].
///
/// This can be used for scenarios where the buffer was written somewhere else but still needed to
/// be tracked.
pub trait Skip: Duplex {
fn skip(&mut self, len: VarInt, final_offset: Option<VarInt>) -> Result<(), Error>;
}
Loading

0 comments on commit 03f97ad

Please sign in to comment.