-
Notifications
You must be signed in to change notification settings - Fork 156
perf(http3): eliminate allocations with zero-copy Bytes
#3010
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ae0d082
8aaa3c2
013518b
0a53834
1776fe8
af45985
6cebdba
86bfd5b
618f3c0
7651468
1bdaaae
f1cb050
906b4dd
d6b102f
bc0f298
54b031f
d6fe04b
29c4633
8b28568
f118659
398eaca
5dd98cf
5272e0a
a04ce1e
586f50d
e795ac1
6c9fe27
04d26ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,138 @@ | ||
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
| // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
| // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
| // option. This file may not be copied, modified, or distributed | ||
| // except according to those terms. | ||
|
|
||
| /// Owned contiguous byte array with an optional offset. | ||
| /// | ||
| /// Inspired by `bytes` crate's `Bytes`. | ||
| #[derive(Debug, Clone)] | ||
| pub struct Bytes { | ||
| data: Vec<u8>, | ||
| offset: usize, | ||
| } | ||
|
|
||
| impl Bytes { | ||
| /// Create a new `Bytes` with the given data and offset. | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// Panics if `offset > data.len()`. | ||
| #[must_use] | ||
| pub fn new(data: Vec<u8>, offset: usize) -> Self { | ||
| assert!( | ||
| offset <= data.len(), | ||
| "offset {offset} is out of bounds for data of length {}", | ||
| data.len() | ||
| ); | ||
| Self { data, offset } | ||
| } | ||
|
|
||
| #[must_use] | ||
| pub fn len(&self) -> usize { | ||
| self.data.len() - self.offset | ||
| } | ||
|
|
||
| #[must_use] | ||
| pub fn is_empty(&self) -> bool { | ||
| self.len() == 0 | ||
| } | ||
|
|
||
| /// Skips the first `n` bytes, consuming and returning `self`. | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// Panics if `n > self.len()`. | ||
| #[must_use] | ||
| pub fn skip(mut self, n: usize) -> Self { | ||
| assert!( | ||
| n <= self.len(), | ||
| "cannot skip {n} bytes when only {} bytes remain", | ||
| self.len() | ||
| ); | ||
| self.offset += n; | ||
| self | ||
| } | ||
| } | ||
|
|
||
| impl AsRef<[u8]> for Bytes { | ||
| fn as_ref(&self) -> &[u8] { | ||
| &self.data[self.offset..] | ||
| } | ||
| } | ||
|
|
||
| impl AsMut<[u8]> for Bytes { | ||
| fn as_mut(&mut self) -> &mut [u8] { | ||
| &mut self.data[self.offset..] | ||
|
Check warning on line 67 in neqo-common/src/bytes.rs
|
||
| } | ||
| } | ||
|
|
||
| impl PartialEq for Bytes { | ||
| fn eq(&self, other: &Self) -> bool { | ||
| self.as_ref() == other.as_ref() | ||
| } | ||
| } | ||
|
|
||
| impl Eq for Bytes {} | ||
|
|
||
| impl From<Vec<u8>> for Bytes { | ||
| fn from(data: Vec<u8>) -> Self { | ||
| Self::new(data, 0) | ||
| } | ||
| } | ||
|
|
||
| impl<const N: usize> PartialEq<[u8; N]> for Bytes { | ||
| fn eq(&self, other: &[u8; N]) -> bool { | ||
| self.as_ref() == other.as_slice() | ||
|
Check warning on line 87 in neqo-common/src/bytes.rs
|
||
| } | ||
| } | ||
|
|
||
| impl PartialEq<[u8]> for Bytes { | ||
| fn eq(&self, other: &[u8]) -> bool { | ||
| self.as_ref() == other | ||
|
Check warning on line 93 in neqo-common/src/bytes.rs
|
||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| #[cfg_attr(coverage_nightly, coverage(off))] | ||
| mod tests { | ||
| use crate::Bytes; | ||
|
|
||
| #[test] | ||
| #[should_panic(expected = "offset 4 is out of bounds for data of length 3")] | ||
| fn illegal_offset() { | ||
| _ = Bytes::new(vec![1, 2, 3], 4); | ||
| } | ||
|
|
||
| #[test] | ||
| fn len() { | ||
| let b = Bytes::new(vec![1, 2, 3, 4], 1); | ||
| assert_eq!(b.len(), 3); | ||
| } | ||
|
|
||
| #[test] | ||
| fn is_empty() { | ||
| let b = Bytes::new(vec![1, 2, 3, 4], 4); | ||
| assert!(b.is_empty()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn skip() { | ||
| let b = Bytes::new(vec![1, 2, 3, 4], 1).skip(2); | ||
| assert_eq!(b.as_ref(), &[4]); | ||
| } | ||
|
|
||
| #[test] | ||
| #[should_panic(expected = "cannot skip 4 bytes when only 3 bytes remain")] | ||
| fn illegal_skip() { | ||
| _ = Bytes::new(vec![1, 2, 3, 4], 1).skip(4); | ||
| } | ||
|
|
||
| #[test] | ||
| fn is_equal() { | ||
| let a = Bytes::new(vec![1, 2, 3, 4], 1); | ||
| let b = Bytes::from(vec![2, 3, 4]); | ||
| assert_eq!(a, b); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.