brpc第一周学习分享

    科技2022-07-14  117

    寻求帮助

    由于自己第一次读开源代码,所以完全没有方法,所以第一步是疯狂Google

    brpc学习最佳实践

    如何阅读源代码

    最终找到一篇比较好的文章 如何阅读一份源代码?

    制定计划

    目前自己的大计划是一年能够改写brpc

    所以小计划是当前一个月先搞清楚brpc的基本框架,了解基本结构

    制定以上计划的原因如下:

    自己第一次读大型开源项目这个brpc涉及的知识点较多,工程庞大,而且十分经典实用,所以应该深入学习

    第一周实践

    阅读技巧 https://www.codedump.info/post/20200605-how-to-read-code-v2020/

    然后跟着brpc学习 慢慢来的, 2020年09月28日16:33:07 发现其中AutoReset<>类是第一个简单易懂的类___继续加油

    IOBuf

    声明在iobuf.h,然后实现在iobuf_inl.h 和 iobuf.cpp 中

    cntn问题__TODO

    size_t IOBuf::cutn(std::string* out, size_t n) { if (n == 0) { return 0; } const size_t len = length(); if (n > len) { n = len; } const size_t old_size = out->size(); out->resize(out->size() + n); return cutn(&(*out)[old_size], n); }

    这个cntn在if (n > len)处的操作有点迷惑,因为凭空就把n缩小了

    cut_until理解

    brpc之iobuf中说道: cut_until,从前到后开始cut,直到遇到字符匹配到delim,如果没有匹配到返回-1; 需要注意的地方时,这个地方delim字符串的长度不能超过unsiged long的长度,因为brpc中将字符串hash到一个unsigned long型的整数,然后遍历匹配的时候,也将IOBuf中的字符串hash到一个unsigned long类型的整数,与delim进行比较;这个地方比较精巧的是,hash的时候使用位移操作,向左移,后面的字符串会把前面的字符串冲掉,因此复杂度从 O(N*M) 降到O(N),其中N为block中字符串的长度,M为delim的长度;

    我一开始不懂,后面想到其实可能是因为这个hash只能对字符一直加和,但是不能取模,因为取模就会导致类似hash碰撞的事情,所以就不一定是真的字符匹配了(我猜的)

    append_from_file_descriptor 读fd___ 有点精妙

    看一下实现代码,主要做了三件事:

    循环block,准备好readv函数的参数地址(将block的可写首地址和可写长度依次获取,放入到iovec的数组中) 调用pread函数将读取到的内容写入到上面准备的地址,获取读取的总长度nr; 整理现有的block,因为现有的Block可能很多写满了。

    ssize_t IOPortal::pappend_from_file_descriptor( int fd, off_t offset, size_t max_count) { iovec vec[MAX_APPEND_IOVEC]; int nvec = 0; size_t space = 0; Block* prev_p = NULL; Block* p = _block; // Prepare at most MAX_APPEND_IOVEC blocks or space of blocks >= max_count do { if (p == NULL) { p = iobuf::acquire_tls_block(); if (BAIDU_UNLIKELY(!p)) { errno = ENOMEM; return -1; } if (prev_p != NULL) { prev_p->portal_next = p; } else { _block = p; } } vec[nvec].iov_base = p->data + p->size; vec[nvec].iov_len = std::min(p->left_space(), max_count - space); space += vec[nvec].iov_len; ++nvec; if (space >= max_count || nvec >= MAX_APPEND_IOVEC) { break; } prev_p = p; p = p->portal_next; } while (1); ssize_t nr = 0; if (offset < 0) { nr = readv(fd, vec, nvec); } else { static iobuf::iov_function preadv_func = iobuf::get_preadv_func(); nr = preadv_func(fd, vec, nvec, offset); } if (nr <= 0) { // -1 or 0 if (empty()) { return_cached_blocks(); } return nr; } size_t total_len = nr; do { const size_t len = std::min(total_len, _block->left_space()); total_len -= len; const IOBuf::BlockRef r = { _block->size, (uint32_t)len, _block }; _push_back_ref(r); _block->size += len; if (_block->full()) { Block* const saved_next = _block->portal_next; _block->dec_ref(); // _block may be deleted _block = saved_next; } } while (total_len); return nr; } inline ssize_t IOPortal::append_from_file_descriptor(int fd, size_t max_count) { return pappend_from_file_descriptor(fd, -1, max_count); }

    Containers

    flatmap

    hash

    有趣的[]源码

    template <typename _K, typename _T, typename _H, typename _E, bool _S> _T& FlatMap<_K, _T, _H, _E, _S>::operator[](const key_type& key) { const size_t index = flatmap_mod(_hashfn(key), _nbucket); Bucket& first_node = _buckets[index]; if (!first_node.is_valid()) { ++_size; if (_S) { bit_array_set(_thumbnail, index); } new (&first_node) Bucket(key); return first_node.element().second_ref(); } if (_eql(first_node.element().first_ref(), key)) { return first_node.element().second_ref(); } Bucket *p = first_node.next; if (NULL == p) { if (is_too_crowded(_size)) { if (resize(_nbucket + 1)) { return operator[](key); } // fail to resize is OK } ++_size; Bucket* newp = new (_pool.get()) Bucket(key); first_node.next = newp; return newp->element().second_ref(); } while (1) { if (_eql(p->element().first_ref(), key)) { return p->element().second_ref(); } if (NULL == p->next) { if (is_too_crowded(_size)) { if (resize(_nbucket + 1)) { return operator[](key); } // fail to resize is OK } ++_size; Bucket* newp = new (_pool.get()) Bucket(key); p->next = newp; return newp->element().second_ref(); } p = p->next; } }

    TODO_code_双缓冲数据 DoublyBufferedData

    2020年10月01日19:22:10 今天花了一段时间看完了官方参考资料:https://github.com/apache/incubator-brpc/blob/master/docs/cn/lalb.md

    感觉很有计算含量,所以明天继续看一下代码___2020年10月02日19:01:46 决定暂时宏观层面先学习,所以这个细致代码暂缓

    protobuf

    client

    https://github.com/apache/incubator-brpc/blob/master/docs/cn/client.md

    TODO未懂含义_c_murmurhash or c_md5

    TODO

    默认是IOBuf是small view,只有在两个refs种都存储了不同的的Block之后,才自动转为BigView,可以参考iobuf.cpp:601行____这里没有看懂,2020年09月29日20:54:48
    Processed: 0.010, SQL: 8