ISE -- I/O Buffer 之 STL vector学习
来源:互联网 发布:大数据云计算考研 编辑:程序博客网 时间:2024/06/08 15:31
0x01 缘起
在高性能服务器开发的过程中,良好的IO缓存是整个设计比较重要的环节。带着这方面的兴趣,阅读了开源ISE的IO Buffer设计,不评估其优劣,纯粹学习这方面知识,深度学习下STL vector容器的使用和内存的管理。
0x02 IO Buffer介绍
消息缓存,主要存储socket接收和发送的消息。发送消息时,将消息有序的缓存到buffer中;消息接收时,将消息存放在缓存中,进行拼包,还原出完整的消息。
0x03 ISE IO Buffer
///////////////////////////////////////////////////////////////////////////////// class IoBuffer - 输入输出缓存//// +-----------------+------------------+------------------+// | useless bytes | readable bytes | writable bytes |// | | (CONTENT) | |// +-----------------+------------------+------------------+// | | | |// 0 <= readerIndex <= writerIndex <= sizeclass IoBuffer{public: enum { INITIAL_SIZE = 1024 }; //Buffer初始化大小public: IoBuffer(); ~IoBuffer(); /* const 成员函数,不能修改类成员; * 获取可以读的有效字节; * */ int getReadableBytes() const { return writerIndex_ - readerIndex_; } /* * 获取可以写的有效空间字节数; * */ int getWritableBytes() const { return (int)buffer_.size() - writerIndex_; } /* * 获取可以目前已经读取完,认为无效的空间字节数; * */ int getUselessBytes() const { return readerIndex_; } /* * 追加一个字符串对象到缓存; * */ void append(const string& str); /* * 追加一个指针对象 bytes个字节到缓存; * */ void append(const void *data, int bytes); /* * 向缓存追加 bytes 个字节并填充为'\0'; * */ void append(int bytes); /*从缓存读取 bytes 个字节数据*/ void retrieve(int bytes); /*从缓存读取全部可读数据并存入 str 中*/ void retrieveAll(string& str); /*从缓存读取全部可读数据,相当于清空*/ void retrieveAll(); /*交换一个IO缓存*/ void swap(IoBuffer& rhs); /* 获取读的起始指针 ,访问一个只读指针 */ const char* peek() const { return getBufferPtr() + readerIndex_; }private: /* 获取缓存的起始指针 */ char* getBufferPtr() const { return (char*)&*buffer_.begin(); } /* 获取写位置的起始指针 */ char* getWriterPtr() const { return getBufferPtr() + writerIndex_; } /* 扩展缓存 */ void makeSpace(int moreBytes);private: std::vector<char> buffer_; //buffer 缓存容器,内存的扩展 int readerIndex_; //读指针 int writerIndex_; //写指针};关键代码段,内存扩展:
//-----------------------------------------------------------------------------// 描述: 扩展缓存空间以便可再写进 moreBytes 个字节//-----------------------------------------------------------------------------void IoBuffer::makeSpace(int moreBytes){/*如果无用的字节空间和可以写的字节空间小于需要写入的空间,就调用resize调整扩大 * vector容量,满足值的写入; * vector容量会成倍扩张,INITIAL_SIZE*2, * 并将原来的从就的地方拷贝到新的;*/ if (getWritableBytes() + getUselessBytes() < moreBytes) { buffer_.resize(writerIndex_ + moreBytes); } else { /*如果大于,调整目前的位置,将内存移动一次,将全部可读数据移至缓存开始处*/ int readableBytes = getReadableBytes(); char *buffer = getBufferPtr(); memmove(buffer, buffer + readerIndex_, readableBytes); readerIndex_ = 0; writerIndex_ = readerIndex_ + readableBytes; ISE_ASSERT(readableBytes == getReadableBytes()); }}
后面将详细讲解vector扩容等知识点。
0x04 STL vector
类关键片段:
// 默认allocator为alloc, 其具体使用版本请参照<stl_alloc.h> template <class T, class Alloc = alloc> class vector { public: // 标记为'STL标准强制要求'的typedefs用于提供iterator_traits<I>支持 typedef T value_type; // STL标准强制要求 typedef value_type* pointer; // STL标准强制要求 typedef const value_type* const_pointer; // 由于vector的特性, 一般我们实作的时候都分配给其连续的内存空间, // 所以其迭代器只需要定义成原生指针即可满足需要 typedef value_type* iterator; // STL标准强制要求 typedef const value_type* const_iterator; typedef value_type& reference; // STL标准强制要求 typedef const value_type& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; // STL标准强制要求 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION typedef reverse_iterator<const_iterator> const_reverse_iterator; typedef reverse_iterator<iterator> reverse_iterator; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ typedef reverse_iterator<const_iterator, value_type, const_reference, difference_type> const_reverse_iterator; typedef reverse_iterator<iterator, value_type, reference, difference_type> reverse_iterator; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ protected: // 这个提供STL标准的allocator接口 typedef simple_alloc<value_type, Alloc> data_allocator; iterator start; // 内存空间起始点 iterator finish; // 当前使用的内存空间结束点 iterator end_of_storage; // 实际分配内存空间的结束点 void insert_aux(iterator position, const T& x); .................... }详细讲解resize函数:
void resize(size_type __new_size, const _Tp& __x) { if (__new_size < size()) erase(begin() + __new_size, end()); else insert(end(), __new_size - size(), __x); } void resize(size_type __new_size) { resize(__new_size, _Tp()); }
resize()的作用是改变vector中元素的数目:
1、如果n比当前的vector元素数目要小,vector的容量要缩减到resize的第一个参数大小,既n。并移除那些超出n的元素同时销毁他们。
2、如果n比当前vector元素数目要大,在vector的末尾扩展需要的元素数目,如果第二个参数val指定了,扩展的新元素初始化为val的副本,否则按类型默认初始化。
注意:如果n大于当前的vector的容量(是容量,并非vector的size),将会引起自动内存分配。所以现有的pointer,references,iterators将会失效。
0x05 额外补充const
1、const成员函数不允许修改它所在对象的任何一个数据成员,const成员函数能够访问对象的const成员,而其他成员函数则不可以。
2、对于const类对象/指针/引用可以调用const成员函数,但是不可以调用非const类型的成员函数
2、对于const类对象/指针/引用可以调用const成员函数,但是不可以调用非const类型的成员函数
阅读全文
0 0
- ISE -- I/O Buffer 之 STL vector学习
- I/O之内核buffer-“buffer cache”
- I/O之内核buffer-“buffer cache”
- STL学习之vector
- STL学习之Vector
- STL学习之vector
- STL之vector学习
- STL学习之vector
- STL学习之vector
- 唯快不破:I/O之内核buffer-“buffer cache”
- STL学习之vector容器
- [转载]STL学习之Vector
- STL之vector学习笔记
- Java 7之异步I/O第3篇 - 异步I/O操作之Buffer
- I/O学习之小结
- java学习之i/o
- STL学习之vector(1)
- 初学者学习C++STL之vector容器
- jQuery<6.1>
- Android使用POI打开word文档
- 将VR融入无人机,Parrot推出两款新手无人机套餐
- offsetLeft,Left,clientLeft的区别
- Spring Cloud之Netflix
- ISE -- I/O Buffer 之 STL vector学习
- Spring上下文获取
- 内核源码--------mm_init_cpumask(&init_mm);
- ubuntu16.04 ros系统下杉川/大族激光的使用笔记
- YARN源码分析之ApplicationMaster分配策略
- 欢迎使用CSDN-markdown编辑器
- c++11随机数产生器default_random_engine
- zookeeper在dubbo起了什么作用
- ios widget 与 3D touch