本节主要介绍缓冲相关的传输类,缓存的作用就是为了提高读写的效率。Thrift在实现缓存传输的 时候首先建立一个缓存的基类,然后需要实现缓存功能的类都可以直接从这个基类继承。下面就详细分 析这个基类以及一个具体的实现类。
缓存基类TBufferBase
缓存基类就是让传输类所有的读写函 数都提供缓存来提高性能。它在通常情况下采用memcpy来设计和实现快路径的读写访问操作,这些操作 函数通常都是小、非虚拟和内联函数。TBufferBase是一个抽象的基类,子类必须实现慢路径的读写函 数等操作,慢路径的读写等操作主要是为了在缓存已经满或空的情况下执行。首先看看缓存基类的定义 ,代码如下:
class TBufferBase : public TVirtualTransport<TBufferBase> { public: uint32_t read(uint8_t* buf, uint32_t len) {//读函数 uint8_t* new_rBase = rBase_ + len;//得到需要读到的缓存边界 if (TDB_LIKELY(new_rBase <= rBound_)) {//判断缓存是否有足够的数据可读,采用了分支预测技术 std::memcpy(buf, rBase_, len);//直接内存拷贝 rBase_ = new_rBase;//更新新的缓存读基地址 return len;//返回读取的长度 } return readSlow(buf, len);//如果缓存已经不能够满足读取长度需要就执行慢读 } uint32_t readAll(uint8_t* buf, uint32_t len) { uint8_t* new_rBase = rBase_ + len;//同read函数 if (TDB_LIKELY(new_rBase <= rBound_)) { std::memcpy(buf, rBase_, len); rBase_ = new_rBase; return len; } return apache::thrift::transport::readAll(*this, buf, len);//调用父类的 } void write(const uint8_t* buf, uint32_t len) {//快速写函数 uint8_t* new_wBase = wBase_ + len;//写入后的新缓存基地址 if (TDB_LIKELY(new_wBase <= wBound_)) {//判断缓存是否有足够的空间可以写入 std::memcpy(wBase_, buf, len);//内存拷贝 wBase_ = new_wBase;//更新基地址 return; } writeSlow(buf, len);//缓存空间不足就调用慢写函数 } const uint8_t* borrow(uint8_t* buf, uint32_t* len) {//快速路径借 if (TDB_LIKELY(static_cast<ptrdiff_t>(*len) <= rBound_ - rBase_)) {//判断是否足够借的长度 *len = static_cast<uint32_t>(rBound_ - rBase_); return rBase_;//返回借的基地址 } return borrowSlow(buf, len);//不足就采用慢路径借 } void consume(uint32_t len) {//消费函数 if (TDB_LIKELY(static_cast<ptrdiff_t>(len) <= rBound_ - rBase_)) {//判断缓存是否够消费 rBase_ += len;//更新已经消耗的长度 } else { throw TTransportException(TTransportException::BAD_ARGS, "consume did not follow a borrow.");//不足抛异常 } } protected: virtual uint32_t readSlow(uint8_t* buf, uint32_t len) = 0;//慢函数 virtual void writeSlow(const uint8_t* buf, uint32_t len) = 0; virtual const uint8_t* borrowSlow(uint8_t* buf, uint32_t* len) = 0; TBufferBase() : rBase_(NULL) , rBound_(NULL) , wBase_(NULL) , wBound_(NULL) {}//构造函数,把所有的缓存空间设置为NULL void setReadBuffer(uint8_t* buf, uint32_t len) {//设置读缓存空间地址 rBase_ = buf;//读缓存开始地址 rBound_ = buf+len;//读缓存地址界限 } void setWriteBuffer(uint8_t* buf, uint32_t len) {//设置写缓存地址空间 wBase_ = buf;//起 wBound_ = buf+len;//边界 } virtual ~TBufferBase() {} uint8_t* rBase_;//读从这儿开始 uint8_t* rBound_;//读界限 uint8_t* wBase_;//写开始地址 uint8_t* wBound_;//写界限 };
从TBufferBase定义可以看出,它也是从虚拟类继承,主要采用了memcpy函数来实现缓存的 快速读取,在判断是否有足够的缓存空间可以操作时采用了分支预测技术来提供代码的执行效率,且所 有快路径函数都是非虚拟的、内联的小代码量函数。下面继续看看一个具体实现缓存基类的一个子类的 情况!
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索函数
, 缓存
, 传输
, thrift
, 缓冲
, 路径
, 基类
, 一个
, 缓存类
, 读写缓冲
操作基类
thrift ttransport、tbufferedtransport、thrift transport、thrift transport协议、ttransportexception,以便于您获取更多的相关知识。