zoukankan      html  css  js  c++  java
  • 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;
        }
    
  • 相关阅读:
    Silverlight项目开发准则
    WCF序列化65536大小限制的问题
    自定义的asp.net翻页控件
    解决Process因缓冲区满而导至进程阻塞的办法
    选择适合的Silverlight通信技术
    深入剖析WCF的可靠会话[实例篇](内含美女图片,定力差者慎入)
    25个强大的 jQuery 砌体网页设计作品
    Silverlight 4常用StringFormat格式总结
    C# 发送邮件内容嵌入图片
    如何解决Silverlight跨域访问安全性问题
  • 原文地址:https://www.cnblogs.com/ukernel/p/9191065.html
Copyright © 2011-2022 走看看