Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

零拷贝缓冲区

简介

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() constbool empty() constsize_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() 暴露底层块指针,仅在对应帧有效期内可用;请在对象生命周期内使用。