brpc-iobuf

iobuf:

block:

 197 struct IOBuf::Block {
 198     butil::atomic<int> nshared;
 199     uint16_t flags;
 200     uint16_t abi_check;  // original cap, never be zero.
 201     uint32_t size;
 202     uint32_t cap;
 203     Block* portal_next; //常规不触发,某些场景使用
 207     char* data;

一个共享块,分配block后,持有之,这是一块大内存,头部是block元数据,后面是data,目前感觉data指针多余;通过nshared共享,该值内存顺序是memory_order_relaxed,只保证当前操作的原子性,不考虑线程间的同步,其他线程可能读到新值,也可能读到旧值。

构造iobuf,magic默认0,因此默认使用bigview:

 86     struct BigView {
 87         int32_t magic;
 88         uint32_t start;//ref头
 89         BlockRef* refs;
 90         uint32_t nref;//ref个数
 91         uint32_t cap_mask;
 92         size_t nbytes;//总字节数
        };


 74     struct BlockRef {
 75         // NOTICE: first bit of `offset' is shared with BigView::start
 76         uint32_t offset;
 77         uint32_t length;
 78         Block* block;
 79     };

refs是个数组,可用快速定位ref,每创建一个block都创建对应的BlockRef,存入refs;

这时候,iobuf整个结构应该也清晰了

append操作:

  • 如果是1个字符调用push_back-》iobuf::share_tls_block()
  1. 这里获取g_tls_data,看下数据结构
  2.  318 struct TLSData {
     319     // Head of the TLS block chain.
     320     IOBuf::Block* block_head;
     321 
     322     // Number of TLS blocks
     323     int num_blocks;
     324 
     325     // True if the remote_tls_block_chain is registered to the thread.
     326     bool registered;
     327 };
     328 
     329 static __thread TLSData g_tls_data = { NULL, 0, false };
  3. 线程独立的变量,获取head,如果没full、没NULL,通过Block的next指针遍历,如果full,减少引用计数
  4. 如果仍为NULL,创建新的block,num_blocks+1,覆盖block_head;
  5. 然后直接操作block的data,写入数据,查找refs中的位置,然后更新数据,增加nref值(表示ref个数)
  6. 常规使用,不会涉及tls,IOPortal和zerostream会使用

append是尾部操作,弹出有尾部弹出和头部弹出(pop_front,pop_back);

支持的特性比较多:

比如snappy压缩,ZeroCopyInputStream;

IOPortal支持fd读写,ssl读写,调用系统函数,readv/preadv;

IOBufAppender,没继承iobuf,append性能更好;

IOBuf之间交互,eg:拷贝构造,赋值,cut,append;基本做到零拷贝,通过Block引用计数,以及blockRef控制字节读取offset、length;

问题:

持续尾部写入,头部读取,导致start前移,不能循环使用,导致重新分配二倍空间;

想直接提取数据,cut,copy,fetch等操作会触发拷贝;不过确实,如果直接拿数据使用是存在风险的,通过IOBuf间接使用也是可以的;

使用场景:

正如doc所说,不适合程序内的通用结构;

适合IO,无修改的这种场景;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyObject-C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值