本节书摘来自华章出版社《Ceph源码分析》一书中的第2章,第2.2节Buffer,作者常涛,更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.2 Buffer
Buffer就是一个命名空间,在这个命名空间下定义了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
map<pair<size_t, size_t>, pair<uint32_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校验。

《Ceph源码分析》——第2章,第2节Buffer相关推荐

  1. 《Ceph源码分析》——第1章,第5节RADOS

    本节书摘来自华章出版社<Ceph源码分析>一书中的第1章,第1.5节RADOS,作者常涛,更多章节内容可以访问云栖社区"华章计算机"公众号查看 1.5 RADOS RA ...

  2. 《Ceph源码分析》——第1章,第一节Ceph的发展历程

    本节书摘来自华章出版社<Ceph源码分析>一书中的第1章,第1.1节Ceph的发展历程,作者常涛,更多章节内容可以访问云栖社区"华章计算机"公众号查看 第1章 Ceph ...

  3. 《Ceph源码分析》——导读

    本节书摘来自华章出版社<Ceph源码分析>一书中的导读,作者常涛,更多章节内容可以访问云栖社区"华章计算机"公众号查看 目 录 序言 第1章 Ceph整体架构 1.1 ...

  4. Netty源码分析第6章(解码器)----第4节: 分隔符解码器

    Netty源码分析第6章(解码器)---->第4节: 分隔符解码器 Netty源码分析第六章: 解码器 第四节: 分隔符解码器 基于分隔符解码器DelimiterBasedFrameDecode ...

  5. Netty源码分析第1章(Netty启动流程)----第4节: 注册多路复用

    Netty源码分析第1章(Netty启动流程)---->第4节: 注册多路复用 Netty源码分析第一章:Netty启动流程   第四节:注册多路复用 回顾下以上的小节, 我们知道了channe ...

  6. Netty源码分析第7章(编码器和写数据)----第2节: MessageToByteEncoder

    Netty源码分析第7章(编码器和写数据)---->第2节: MessageToByteEncoder Netty源码分析第七章: Netty源码分析 第二节: MessageToByteEnc ...

  7. Netty源码分析第5章(ByteBuf)----第5节: directArena分配缓冲区概述

    Netty源码分析第5章(ByteBuf)---->第5节: directArena分配缓冲区概述 Netty源码分析第五章: ByteBuf 第五节: directArena分配缓冲区概述 上 ...

  8. 「Ceph源码分析」纠删码解码

    存储系统:ceph-14.2.22 操作系统:ubuntu-server-18.04 总体框架 源码分析 ECBackend::objects_read_and_reconstruct [ 文件路径 ...

  9. Vue源码分析——第三章

    Vue源码分析--第一章 Vue源码分析--第二章 // only used in dev mode//检测 val必需是数字function checkDuration(val, name, vno ...

最新文章

  1. smartClient 2--可视化组件
  2. Eclipse相关问题总结
  3. JVM-分代垃圾回收器
  4. jQuery-helloWorld
  5. 【机器学习】机器学习中缺失值处理方法大全(附代码)
  6. matlab数值过小为0,MATLAB数值计算——0
  7. 简单粗暴的多目标跟踪神器 – DeepSort
  8. 问题 H: 简单的打折计算 山东科技大学OJ C语言
  9. 设计mysql存储过程,MySQL的存储过程设计的例子
  10. 重新leetcode第1天——二叉树遍历算法讲解合集
  11. Box2DWeb_04之碰撞检测
  12. VLFeat在matlab和vs中安装
  13. 泛微oa系统什么框架_泛微OA系统怎么样?与其他OA相比呢?
  14. 极狐GitLab硬实力助力中国开源生态建设
  15. 无人机技术的发展与应用
  16. 冷补丁和热补丁的区别
  17. 微型计算机中内存比外存怎样,在同一台计算机中,内存比外存( )。
  18. 985北京航空航天大学软件考研改考!数据结构+软件工程+操作系统
  19. 【第176期】游戏策划:你身边有暴脾气的同事?那恭喜你了
  20. windebug 指令详解

热门文章

  1. 安卓UI测试(基于android studio环境 espresso框架)
  2. 幂等和高并发在电商系统中的使用
  3. This version of MySQL doesn't yet support 'LIMIT IN/ALL/ANY/SOME subquery 解决方法
  4. 物联网通讯协议:MQTT,NB-IOT,Zigbee,CoAP,RFID,BLUETOOTH,NFC,4G,HTTP
  5. 安卓app与阿里云服务器的无线通信(非局域网)
  6. nginx配置php 9000,Nginx支持php配置
  7. 体重 年龄 性别 身高 预测鞋码_【新手扫盲】身高体重性别年龄身体素质影响玩滑板吗?...
  8. RocketMQ中的死信队列
  9. html转excel有问题,html转excel
  10. 网络安全:堡垒机相关知识介绍