BytesMut
这一部分讲构建主线:一个可写的 BytesMut 怎么在写入、切分、扩容之间尽量不拷贝,最后不拷贝地变成 Bytes。代码在 src/bytes_mut.rs,2.0k 行。写入用的 BufMut 接口在下一部分 Buf 与 BufMut。
三章按「先看结构,再看两种操作」排列:
- data 字段的编码:
data最低位区分KIND_VEC(独占一个Vec,其余位记 3 位的原始容量和前面切掉的偏移)和KIND_ARC(指向Shared);偏移超过MAX_VEC_POS时提升;用一个程序把每一步的位打印出来,并看到从with_capacity(0)起步的缓冲原始容量是 0。 - split 与 freeze:
split_to、split_off、split第一次调用时把KIND_VEC提升成KIND_ARC,计数从 2 开始;freeze对KIND_VEC走From<Vec<u8>>,对KIND_ARC只换一张 vtable;unsplit和try_unsplit何时 O(1)。 - reserve:
reserve_inner在KIND_VEC时把数据挪回开头或交给Vec::reserve,在KIND_ARC时唯一就原地复用或扩大,不唯一就按max(需求, 原始容量)另分配、回到KIND_VEC;try_reclaim与extend_from_within。
flowchart TB wc["with_capacity:KIND_VEC"] --> wr["写入:BufMut"] wr --> sp["split_to:提升 KIND_ARC"] sp --> fz["freeze:交给 Bytes"] sp --> rs["reserve"] rs -->|唯一| reuse["原地复用"] rs -->|还有别人| alloc["另分配:回到 KIND_VEC"] reuse --> wr alloc --> wr
freeze 之后的 clone、切片和 drop 是共享主线,在 02 Bytes。hyper 的读缓冲就是一个 BytesMut,它怎么用这三章里的操作,见 一块缓冲的一生 和 hyper 卷的 读写缓冲。
💬 关联讨论
发起讨论加载中...