今天介绍的是一种缓冲区由于我在学习服务器认识到一种缓冲区觉得设计的还挺好的所以就介绍给大家。先看整体的代码static const int kPrePendIndex 8; // prependindex长度 static const int kInitalSize 1024; // 初始化开辟空间长度 class Buffer{ public: DISALLOW_COPY_AND_MOVE(Buffer); Buffer(); ~Buffer(); // buffer的起始位置 char *begin(); // const对象的begin函数使得const对象调用begin函数时 // 所得到的迭代器只能对数据进行读操作而不能进行修改 const char *begin() const; char *beginread(); const char *beginread() const; char *beginwrite(); const char *beginwrite() const; // 添加数据 void Append(const char *message); void Append(const char *message, int len); void Append(const std::string message); // 获得可读大小等 int readablebytes() const; int writablebytes() const; int prependablebytes() const; // 查看数据但是不更新read_index_位置 char *Peek(); const char *Peek() const; std::string PeekAsString(int len); std::string PeekAllAsString(); // 取数据取出后更新read_index,相当于不可重复取 // 定长 void Retrieve(int len); std::string RetrieveAsString(int len); // 全部 void RetrieveAll(); std::string RetrieveAllAsString(); // 某个索引之前 void RetrieveUtil(const char *end); std::string RetrieveUtilAsString(const char *end); //查看空间 void EnsureWritableBytes(int len); private: std::vectorchar buffer_; int read_index_; int write_index_; };这个缓冲区适用于可读可写的情况他里面有三个模块最前边的是prependable中间是readable后边是writable版本快。分别是预留可读可写板块。这里面的预留和已读板块是放在一起说的。他的最大的特点就是可以压缩掉已读的空间将可读空间往前copy一下每次追加新的数据就会执行一个判断语句if可写的数据大小lenwritable那么就是直接写else if查看压缩后是否够用如果够用就压缩然后追加else压缩过还不够只能增加writable的大小了我们这里的缓冲区维护的是vector的数组所以可以resize大小我们看一下代码void Buffer::EnsureWritableBytes(int len){ if(writablebytes() len) return; if(writablebytes() prependablebytes() kPrePendIndex len){ // 如果此时writable和prepenable的剩余空间超过写的长度则先将已有数据复制到初始位置 // 将不断读导致的read_index_后移使前方没有利用的空间利用上。 std::copy(beginread(), beginwrite(), begin() kPrePendIndex); write_index_ kPrePendIndex readablebytes(); read_index_ kPrePendIndex; }else{ buffer_.resize(write_index_ len); } }其次就是维护两个索引来计算预留可读可写空间。int read_index_; int write_index_;0preread_index_write_index_buffer.size()preread_index_-perwirte_index_-read_index_buffer.size()-write_Index_预留空间大侠已读大小可读大小可写大小缓冲区大小剩下的就是一些Retrieve的功能逻辑比较简单这里不在一一赘述其实这个预留空间目前并没有用到其实是非常有用的有的时候问们要先在缓冲过去写入正文然后再写进缓冲区可以用来封装报头。
缓冲区Buffer(带廉价前置空间的可压缩线性缓冲区)
今天介绍的是一种缓冲区由于我在学习服务器认识到一种缓冲区觉得设计的还挺好的所以就介绍给大家。先看整体的代码static const int kPrePendIndex 8; // prependindex长度 static const int kInitalSize 1024; // 初始化开辟空间长度 class Buffer{ public: DISALLOW_COPY_AND_MOVE(Buffer); Buffer(); ~Buffer(); // buffer的起始位置 char *begin(); // const对象的begin函数使得const对象调用begin函数时 // 所得到的迭代器只能对数据进行读操作而不能进行修改 const char *begin() const; char *beginread(); const char *beginread() const; char *beginwrite(); const char *beginwrite() const; // 添加数据 void Append(const char *message); void Append(const char *message, int len); void Append(const std::string message); // 获得可读大小等 int readablebytes() const; int writablebytes() const; int prependablebytes() const; // 查看数据但是不更新read_index_位置 char *Peek(); const char *Peek() const; std::string PeekAsString(int len); std::string PeekAllAsString(); // 取数据取出后更新read_index,相当于不可重复取 // 定长 void Retrieve(int len); std::string RetrieveAsString(int len); // 全部 void RetrieveAll(); std::string RetrieveAllAsString(); // 某个索引之前 void RetrieveUtil(const char *end); std::string RetrieveUtilAsString(const char *end); //查看空间 void EnsureWritableBytes(int len); private: std::vectorchar buffer_; int read_index_; int write_index_; };这个缓冲区适用于可读可写的情况他里面有三个模块最前边的是prependable中间是readable后边是writable版本快。分别是预留可读可写板块。这里面的预留和已读板块是放在一起说的。他的最大的特点就是可以压缩掉已读的空间将可读空间往前copy一下每次追加新的数据就会执行一个判断语句if可写的数据大小lenwritable那么就是直接写else if查看压缩后是否够用如果够用就压缩然后追加else压缩过还不够只能增加writable的大小了我们这里的缓冲区维护的是vector的数组所以可以resize大小我们看一下代码void Buffer::EnsureWritableBytes(int len){ if(writablebytes() len) return; if(writablebytes() prependablebytes() kPrePendIndex len){ // 如果此时writable和prepenable的剩余空间超过写的长度则先将已有数据复制到初始位置 // 将不断读导致的read_index_后移使前方没有利用的空间利用上。 std::copy(beginread(), beginwrite(), begin() kPrePendIndex); write_index_ kPrePendIndex readablebytes(); read_index_ kPrePendIndex; }else{ buffer_.resize(write_index_ len); } }其次就是维护两个索引来计算预留可读可写空间。int read_index_; int write_index_;0preread_index_write_index_buffer.size()preread_index_-perwirte_index_-read_index_buffer.size()-write_Index_预留空间大侠已读大小可读大小可写大小缓冲区大小剩下的就是一些Retrieve的功能逻辑比较简单这里不在一一赘述其实这个预留空间目前并没有用到其实是非常有用的有的时候问们要先在缓冲过去写入正文然后再写进缓冲区可以用来封装报头。