Refactor Bytes to use an internal vtable (#298)

Bytes is a useful tool for managing multiple slices into the same region
of memory, and the other things it used to have been removed to reduce
complexity. The exact strategy for managing the multiple references is
no longer hard-coded, but instead backing by a customizable vtable.

- Removed ability to mutate the underlying memory from the `Bytes` type.
- Removed the "inline" (SBO) mechanism in `Bytes`. The reduces a large
  amount of complexity, and improves performance when accessing the
  slice of bytes, since a branch is no longer needed to check if the
  data is inline.
- Removed `Bytes` knowledge of `BytesMut` (`BytesMut` may grow that
  knowledge back at a future point.)
This commit is contained in:
Sean McArthur
2019-10-16 09:53:36 -07:00
committed by GitHub
parent ebe96021b0
commit 43ac8e5494
17 changed files with 2165 additions and 2818 deletions
-8
View File
@@ -186,14 +186,6 @@ impl<T, U> Buf for Chain<T, U>
n += self.b.bytes_vectored(&mut dst[n..]);
n
}
fn to_bytes(&mut self) -> crate::Bytes {
let mut bytes: crate::BytesMut = self.a.to_bytes().try_mut()
.unwrap_or_else(|bytes| bytes.into());
bytes.put(&mut self.b);
bytes.freeze()
}
}
impl<T, U> BufMut for Chain<T, U>
-19
View File
@@ -20,22 +20,3 @@ impl Buf for VecDeque<u8> {
self.drain(..cnt);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hello_world() {
let mut buffer: VecDeque<u8> = VecDeque::new();
buffer.extend(b"hello world");
assert_eq!(11, buffer.remaining());
assert_eq!(b"hello world", buffer.bytes());
buffer.advance(6);
assert_eq!(b"world", buffer.bytes());
buffer.extend(b" piece");
let mut out = [0; 11];
buffer.copy_to_slice(&mut out);
assert_eq!(b"world piece", &out[..]);
}
}
+354 -2460
View File
File diff suppressed because it is too large Load Diff
+1429
View File
File diff suppressed because it is too large Load Diff
+26 -1
View File
@@ -84,10 +84,13 @@ pub use crate::buf::{
BufMut,
};
mod bytes_mut;
mod bytes;
mod debug;
mod hex;
pub use crate::bytes::{Bytes, BytesMut};
mod loom;
pub use crate::bytes_mut::BytesMut;
pub use crate::bytes::Bytes;
// Optional Serde support
#[cfg(feature = "serde")]
@@ -96,3 +99,25 @@ mod serde;
// Optional `Either` support
#[cfg(feature = "either")]
mod either;
#[inline(never)]
#[cold]
fn abort() -> ! {
#[cfg(feature = "std")]
{
std::process::abort();
}
#[cfg(not(feature = "std"))]
{
struct Abort;
impl Drop for Abort {
fn drop(&mut self) {
panic!();
}
}
let _a = Abort;
panic!("abort");
}
}
+5
View File
@@ -0,0 +1,5 @@
pub(crate) mod sync {
pub(crate) mod atomic {
pub(crate) use core::sync::atomic::{fence, AtomicPtr, AtomicUsize, Ordering};
}
}
+7 -7
View File
@@ -5,7 +5,7 @@ use serde::{Serialize, Serializer, Deserialize, Deserializer, de};
use super::{Bytes, BytesMut};
macro_rules! serde_impl {
($ty:ident, $visitor_ty:ident, $from_slice:ident) => (
($ty:ident, $visitor_ty:ident, $from_slice:ident, $from_vec:ident) => (
impl Serialize for $ty {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -29,13 +29,13 @@ macro_rules! serde_impl {
where V: de::SeqAccess<'de>
{
let len = cmp::min(seq.size_hint().unwrap_or(0), 4096);
let mut values = Vec::with_capacity(len);
let mut values: Vec<u8> = Vec::with_capacity(len);
while let Some(value) = seq.next_element()? {
values.push(value);
}
Ok(values.into())
Ok($ty::$from_vec(values))
}
#[inline]
@@ -49,7 +49,7 @@ macro_rules! serde_impl {
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where E: de::Error
{
Ok($ty::from(v))
Ok($ty::$from_vec(v))
}
#[inline]
@@ -63,7 +63,7 @@ macro_rules! serde_impl {
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where E: de::Error
{
Ok($ty::from(v))
Ok($ty::$from_vec(v.into_bytes()))
}
}
@@ -78,5 +78,5 @@ macro_rules! serde_impl {
);
}
serde_impl!(Bytes, BytesVisitor, copy_from_slice);
serde_impl!(BytesMut, BytesMutVisitor, from);
serde_impl!(Bytes, BytesVisitor, copy_from_slice, from);
serde_impl!(BytesMut, BytesMutVisitor, from, from_vec);