wordpress 伪静态 后台,北京网站优化专家,国内有做外汇的正规网站吗,wordpress淘宝联盟模板下载地址本节书摘来自华章出版社《Ceph源码分析》一书中的第2章#xff0c;第2.2节Buffer#xff0c;作者常涛#xff0c;更多章节内容可以访问云栖社区“华章计算机”公众号查看 2.2 BufferBuffer就是一个命名空间#xff0c;在这个命名空间下定义了Buffer相关的数据结构, 这些数… 本节书摘来自华章出版社《Ceph源码分析》一书中的第2章第2.2节Buffer作者常涛更多章节内容可以访问云栖社区“华章计算机”公众号查看 2.2 BufferBuffer就是一个命名空间在这个命名空间下定义了Buffer相关的数据结构, 这些数据结构在Ceph的源代码中广泛使用。下面介绍的buffer::raw类是基础类其子类完成了Buffer数据空间的分配buffer::ptr类实现了Buffer内部的一段数据buffer::list封装了多个数据段。 2.2.1 buffer::raw类buffer::raw是一个原始的数据Buffer在其基础之上添加了长度、引用计数和额外的crc校验信息结构如下class buffer::raw { public: char *data; //数据指针
unsigned len; //数据长度
atomic_t nref; //引用计数mutable RWLock crc_lock; //读写锁保护crc_map
mappairsize_t, size_t, pairuint32_t, uint32_t crc_map;
//crc校验信息第一个pair为数据段的起始和结束from,to)第二个pair是crc32校验码pair的第一字段为base crc32校验码第二个字段为加上数据段后计算出的crc32校验码。 ……}下列类都继承了buffer::raw实现了data对应内存空间的申请类raw_malloc实现了用malloc函数分配内存空间的功能。类class buffer::raw_mmap_pages实现了通过mmap来把内存匿名映射到进程的地址空间。类class buffer::raw_posix_aligned调用了函数posix_memalign来申请内存地址对齐的内存空间。类class buffer::raw_hack_aligned是在系统不支持内存对齐申请的情况下自己实现了内存地址的对齐。类class buffer::raw_pipe实现了pipe做为Buffer的内存空间。类class buffer::raw_char使用了C的new操作符来申请内存空间。 2.2.2 buffer::ptr类buffer::ptr就是对于buffer::raw的一个部分数据段。结构如下class CEPH_BUFFER_API ptr { raw *_raw; unsigned _off, _len; ……}ptr是raw里的一个任意的数据段_off是在_raw里的偏移量_len是ptr的长度。raw和ptr的示意图如图2-1所示。图2-1 raw和ptr示意图 2.2.3 buffer::list类buffer::list是一个使用广泛的类它是多个buffer::ptr的列表也就是多个内存数据段的列表。结构如下class CEPH_BUFFER_API list { std::list _buffers; //所有的ptr unsigned _len; //所有的ptr的数据总长度 unsigned _memcopy_count; //当调用函数rebuild用来内存对齐时需要内存拷贝的数据量 ptr append_buffer; //当有小的数据就添加到这个buffer里 mutable iterator last_p; //访问list的迭代器 ……}buffer::list的重要的操作如下所示。添加一个ptr到list的头部void push_front(ptr bp) { if (bp.length() 0) return; _buffers.push_front(bp); _len bp.length();}添加一个raw到list头部中先构造一个ptr后添加list中void push_front(raw *r) { ptr bp(r); push_front(bp);}判断内存是否以参数align对齐每一个ptr都必须以align对齐bool buffer::list::is_aligned(unsigned align) const{ for (std::list::const_iterator it _buffers.begin(); it ! _buffers.end();
it) if (!it-is_aligned(align))
return false;
return true; }添加一个字符到list中先查看append_buffer是否有足够的空间如果没有就新申请一个4KB大小的空间void buffer::list::append(char c){ // 检查当前的append_buffer是否有足够的空间 unsigned gap append_buffer.unused_tail_length(); if (!gap) { // 如果没有空间就申请一个append_buffer! append_buffer create_aligned(CEPH_BUFFER_APPEND_SIZE, CEPH_BUFFER_APPEND_SIZE);
append_buffer.set_length(0); //到目前为止没有用到 } append(append_buffer, append_buffer.append(c) - 1, 1);
// 把该数据段添加到append_buffer中 }内存对齐有些情况下需要内存地址对齐例如当以directIO方式写入数据至磁盘时需要内存地址按内存页面大小page对齐也即buffer::list的内存地址都需按page对齐。函数rebuild用来完成对齐的功能。其实现的方法也比较简单检查没有对齐的ptr申请一块新对齐的内存把数据拷贝过去释放内存空间就可以了。buffer::list还集成了其他额外的一些功能把数据写入文件或从文件读取数据的功能。计算数据的crc32校验。