零拷贝缓冲区
简介
asco::io::buffer<CharT>
是一个面向高性能 I/O 的零拷贝缓冲区,支持将多段数据以链式方式拼接、切分与转移,默认字符类型为 char
,也可使用 std::byte
作为纯字节缓冲区。
适用场景:
- 网络/文件 I/O 的分段读写与聚合
- 日志、协议报文、消息的高效拼装
- 需要避免多次内存拷贝的高吞吐场景
核心特点:
- 多种来源零拷贝拼接(原始内存、std::string、std::string_view)
- 消费型与非消费型操作区分清晰(如 to_string/split 为消费型,clone/rawbuffers 为非消费)
- 与标准库良好协作,接口直观
快速上手
using asco::io::buffer;
using namespace std::literals;
// 追加与合并输出(to_string 会消耗自身)
buffer<> b;
b.push('A');
b.push(std::string("SCO"));
b.push("._TEST"sv);
std::string out = std::move(b).to_string(); // "ASCO._TEST"
// 拼接另一个 buffer(源被清空)
buffer<> x, y;
x.push("Hello"sv);
y.push("World"sv);
x.push(std::move(y)); // y 清空
std::string s = std::move(x).to_string(); // "HelloWorld"
// 分割
buffer<> z("HelloWorld"s);
auto [left, right] = std::move(z).split(5); // "Hello" | "World"
// 克隆(非消费式,适合重复读取)
buffer<> a("ASCO"s);
auto c = a.clone();
std::string s1 = std::move(c).to_string(); // "ASCO"
std::string s2 = std::move(a.clone()).to_string(); // 仍可再读
// 覆盖修改(从 start 起以新内容覆盖,可能截断原尾部)
buffer<> m("HelloWorld"s);
buffer<> ins("ASCO"s);
m.modify(5, std::move(ins)); // 结果 "HelloASCOd"
auto rs = std::move(m).to_string();
// 追加零字节(如为定长结构留空位)
buffer<> zf;
zf.push("A"sv);
zf.fill_zero(3);
zf.push("B"sv);
auto zs = std::move(zf).to_string(); // "A\0\0\0B"
// 遍历底层原始块(零拷贝发送)
buffer<> r("AA"s);
auto it = r.rawbuffers();
while (!it.is_end()) {
auto rb = *it; // rb.buffer / rb.size / rb.seq
// 直接用于系统调用或网络发送
++it;
}
常用接口(按用途)
构造与赋值
buffer()
、buffer(CharT)
、buffer(std::basic_string<CharT>&&)
buffer(const std::basic_string_view<CharT>&)
- 支持移动构造/赋值,禁止拷贝
写入与组合
void push(CharT)
void push(std::basic_string<CharT>&&)
void push(const std::basic_string_view<CharT>&)
void push(buffer&&)
(拼接并清空源)void fill_zero(size_t n)
追加 n 个值为 0 的字节/字符void push_raw_array_buffer(CharT* buf, size_t capacity, size_t size, buffer_destroyer* destroyer = nullptr)
直接挂载用户内存
读出与切分
std::basic_string<CharT> to_string(this buffer&&)
合并输出并清空自身(消费型)std::tuple<buffer, buffer> split(this buffer&&, size_t pos)
分割为左右两个 buffer, 并清空自身(消费型),对先前调用clone()
的结果没有副作用
复制与修改
buffer clone() const
非消费式克隆(共享底层数据,适合多次读取)void modify(this buffer&, size_t start, buffer<CharT> buf)
从start
起覆盖写入,对先前调用clone()
的结果没有副作用
状态与工具
size_t size() const
、bool empty() const
、size_t buffer_count() const
void clear()
、void swap(buffer& rhs)
: 对先前调用clone()
的结果没有副作用rawbuffer_iterator rawbuffers() const
遍历底层连续内存块
行为与语义
- 消费型操作:
to_string()
、split()
会清空被调用对象。 - 非消费型操作:
clone()
、rawbuffers()
不改变内容。 push(buffer&&)
会清空源对象(源的内容被整体转移)。- 传入的
std::string_view
不持有所有权;需保证其底层数据在使用期间有效。 - 非线程安全。
错误与边界
split(pos)
与modify(start, ...)
若位置越界将抛出运行时错误。to_string()
/split()
后原对象被清空,再次读取将得到空结果。rawbuffers()
暴露底层块指针,仅在对应帧有效期内可用;请在对象生命周期内使用。