Bytes crate是一个高效的用于存储和操作连续内存的容器,允许多个Bytes对象指向相同的内存,通过引用计数来管理。
BytesMut 提供了可写的Bytes buf,内部是Vec<u8>,默认是KIND_VEC类型,也可以变成KIND_ARC类型,是一个对BytesBufMut的Shared视图,其实本质上就是变成了Arc<Vec<u8>>
pub struct BytesMut {
// 指针指向对应的内存,默认是Vec<u8>
ptr: NonNull<u8>,
len: usize,
cap: usize,
// 存放一些元信息,表明当前是KIND_VEC还是KIND_ARC
data: *mut Shared,
}
提供了freeze方法,可以使其变成只读的Bytes
提供了split_off方法,可以将一个BytesMut切成两个,这个时候每一个ByesMut指向整个Bytes buf的部分,相当于是string view,只读的。
Bytes是只读版本的Bytes buf,其通过Vtable来区分是static bytes,还是Shared的Bytes、还是可变的BytesMut
pub struct Bytes {
ptr: *const u8,
len: usize,
// inlined "trait object"
data: AtomicPtr<()>,
vtable: &'static Vtable,
}
// 相当于VFS,一堆函数指针,感觉这里通过trait也可以实现
pub(crate) struct Vtable {
/// fn(data, ptr, len)
pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes,
/// fn(data, ptr, len)
///
/// takes `Bytes` to value
pub to_vec: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Vec<u8>,
/// fn(data, ptr, len)
pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),
}
// 使用vtable中的function
impl Clone for Bytes {
#[inline]
fn clone(&self) -> Bytes {
unsafe { (self.vtable.clone)(&self.data, self.ptr, self.len) }
}
}
ptr::read(self)
unsafe fn shallow_clone(&mut self) -> BytesMut {
if self.kind() == KIND_ARC {
increment_shared(self.data);
// ptr::read(self),将self转换成了BytesMut
ptr::read(self)
} else {
self.promote_to_shared(/*ref_count = */ 2);
ptr::read(self)
}
}
pub struct BytesMut {
ptr: NonNull<u8>,
len: usize,
cap: usize,
// 这里的data可以是普通的usize,也可以是指向Shared的指针
// 通过data的值其末位的几位来表示其类型,因为指针指向的地址一定是字节对齐的
// 因此最后一位是0,因此这里可以通过末尾的0或者1来表示其类型
data: *mut Shared,
}
// 相当于是一个 Arc<Vec<u8>>,不过是只读的
struct Shared {
vec: Vec<u8>,
original_capacity_repr: usize,
ref_count: AtomicUsize,
}
// 最后一位相与得到真实的地址
#[inline]
fn kind(&self) -> usize {
self.data as usize & KIND_MASK
}
unsafe fn promote_to_shared(&mut self, ref_cnt: usize) {
debug_assert_eq!(self.kind(), KIND_VEC);
debug_assert!(ref_cnt == 1 || ref_cnt == 2);
// 获取到Vec<u8>的capacity
let original_capacity_repr =
(self.data as usize & ORIGINAL_CAPACITY_MASK) >> ORIGINAL_CAPACITY_OFFSET;
// The vec offset cannot be concurrently mutated, so there
// should be no danger reading it.
// 获取Vec<u8>的offset,当前的BytesMut可能是被split的
let off = (self.data as usize) >> VEC_POS_OFFSET;
// First, allocate a new `Shared` instance containing the
// `Vec` fields. It's important to note that `ptr`, `len`,
// and `cap` cannot be mutated without having `&mut self`.
// This means that these fields will not be concurrently
// updated and since the buffer hasn't been promoted to an
// `Arc`, those three fields still are the components of the
// vector.
// 构建shared bytes mut
let shared = Box::new(Shared {
vec: rebuild_vec(self.ptr.as_ptr(), self.len, self.cap, off),
original_capacity_repr,
ref_count: AtomicUsize::new(ref_cnt),
});
let shared = Box::into_raw(shared);
// The pointer should be aligned, so this assert should
// always succeed.
debug_assert_eq!(shared as usize & KIND_MASK, KIND_ARC);
// data指向Shared
self.data = shared;
}