thrift之TTransport层的缓存传输类TBufferedTransport和缓冲基类TBufferBase (一)

2014-11-23 22:13:34 ? 作者: ? 浏览: 15

本节主要介绍缓冲相关的传输类,缓存的作用就是为了提高读写的效率。Thrift在实现缓存传输的时候首先建立一个缓存的基类,然后需要实现缓存功能的类都可以直接从这个基类继承。下面就详细分析这个基类以及一个具体的实现类。
  缓存基类TBufferBase
  缓存基类就是让传输类所有的读写函数都提供缓存来提高性能。它在通常情况下采用memcpy来设计和实现快路径的读写访问操作,这些操作函数通常都是小、非虚拟和内联函数。TBufferBase是一个抽象的基类,子类必须实现慢路径的读写函数等操作,慢路径的读写等操作主要是为了在缓存已经满或空的情况下执行。首先看看缓存基类的定义,代码如下:
[cpp]
  class TBufferBase : public TVirtualTransport {
   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(*len) <= rBound_ - rBase_)) {//判断是否足够借的长度
   *len = static_cast(rBound_ - rBase_);
   return rBase_;//返回借的基地址
   }
   return borrowSlow(buf, len);//不足就采用慢路径借
   }
   void consume(uint32_t len) {//消费函数
   if (TDB_LIKELY(static_cast(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_;//写界限
  };

  class TBufferBase : public TVirtualTransport {
   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;//更新基

-->

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: