UDT源码剖析(八)之Cache

在UDT源代码中,作者使用了std::vectorstd::list组装了一个缓存系统,本来在纠结要不要列出来,没有啥技术含量,不过为了完整性,还是列出来吧...

CCache

class CCache
{
private:
   std::list<T*> m_StorageList;     //定义一个链表,链表中的指针指向缓存的对象(真实存储位置)
   typedef typename std::list<T*>::iterator ItemPtr;    //指向链表结点的iterator
   typedef std::list<ItemPtr> ItemPtrList;  //将指向ListNode的iterator封装成一个链表
   std::vector<ItemPtrList> m_vHashPtr;//HASH表

   int m_iMaxSize;  //最大的数量
   int m_iHashSize; //HASH值
   int m_iCurrSize; //当前数量

   udt_pthread_mutex_t m_Lock;
};
class CInfoBlock
{
public:
   uint32_t m_piIP[4];      //机器可读的IP地址,为了IPV4只占32位,IPV6全部占用
   int m_iIPversion;        // IP version
   uint64_t m_ullTimeStamp; //上一次更新的时间
   int m_iRTT;          //RTT
   int m_iBandwidth;        //估计的带宽
   int m_iLossRate;     //平均丢失速率
   int m_iReorderDistance;  //数据包重新排序距离
   double m_dInterval;      //分组间时间,就是数据包发送的间隔时间,用于拥塞控制
   double m_dCWnd;      //拥塞窗口大小用于拥塞控制
}
  • 初始化:CCache(int size = 1024)

    CCache(int size = 1024):
       m_iMaxSize(size),    
       m_iHashSize(size * 3),
       m_iCurrSize(0)
       {
      m_vHashPtr.resize(m_iHashSize);   //使用resize在HASH中预留位置
      CGuard::createMutex(m_Lock);
       }
  • 销毁:~CCache()

       ~CCache()
       {
      clear();
      CGuard::releaseMutex(m_Lock);
       }

    -在HASH'中进行查找:int lookup(T* data)

       int lookup(T* data)
       {
      CGuard cacheguard(m_Lock);
    
      int key = data->getKey();    //获得在HASH中的索引位置
      if (key < 0)
         return -1;
      if (key >= m_iMaxSize) //如果大于1024
         key %= m_iHashSize; //求在HASH中的位置,找到想应的链表
    
      const ItemPtrList& item_list = m_vHashPtr[key];
      for (typename ItemPtrList::const_iterator i = item_list.begin(); i != item_list.end(); ++ i)
      {
         if (*data == ***i)
         {
            *data = ***i;
            return 0;
         }
      }
    
      return -1;
       }
  • 更新缓存:int update(T* data)

       int update(T* data)
       {
      CGuard cacheguard(m_Lock);
    
      int key = data->getKey();    //同上,先在HASH中寻找槽
      if (key < 0)
         return -1;
      if (key >= m_iMaxSize)
         key %= m_iHashSize;
    
      T* curr = NULL;
    
      ItemPtrList& item_list = m_vHashPtr[key];    
      for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
      {
         if (*data == ***i)
         {
            // update the existing entry with the new value
            ***i = *data;   //找到想要找到的i
            curr = **i;
    
            // remove the current entry
            m_StorageList.erase(*i);    //删除i
            item_list.erase(i);
    
            // re-insert to the front
            m_StorageList.push_front(curr); //调整i的位置,因为最近访问,修改存储位置,加快访问速度
            item_list.push_front(m_StorageList.begin());
    
            return 0;
         }
      }
    
      // create new entry and insert to front
      curr = data->clone(); //如果没有找到,就直接插入
      m_StorageList.push_front(curr);
      item_list.push_front(m_StorageList.begin());
    
      ++ m_iCurrSize;   //增加当前的数量
    
      //如果当前的缓存已经溢出,删除最后一个缓存对象
      if (m_iCurrSize >= m_iMaxSize)
      {
         T* last_data = m_StorageList.back();
         int last_key = last_data->getKey() % m_iHashSize;
    
         item_list = m_vHashPtr[last_key];
         for (typename ItemPtrList::iterator i = item_list.begin(); i != item_list.end(); ++ i)
         {
            if (*last_data == ***i)
            {
               item_list.erase(i);
               break;
            }
         }
    
         last_data->release();
         delete last_data;
         m_StorageList.pop_back();
         -- m_iCurrSize;
      }
    
      return 0;
       }
  • 清理所有缓存:void clear()

       void clear()
       {
      for (typename std::list<T*>::iterator i = m_StorageList.begin(); i != m_StorageList.end(); ++ i)
      {
         (*i)->release();
         delete *i;
      }
      m_StorageList.clear();
      for (typename std::vector<ItemPtrList>::iterator i = m_vHashPtr.begin(); i != m_vHashPtr.end(); ++ i)
         i->clear();
      m_iCurrSize = 0;
    }

猜你喜欢

转载自www.cnblogs.com/ukernel/p/9191065.html