在UDT源代码中,作者使用了std::vector
和std::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; }