/* 简单hash表,用于试着解决一般map查找速度慢的问题,by dzj, 08.09.09; */ #pragma once #include "dshash.h" #include #define USE_SELF_HASH // 使用自实现的hashtb; using namespace std; struct TestInt { public: unsigned int GetKey() { return testKey; }; public: unsigned int testKey; unsigned int testValue; }; ///存放用于hashtb的指针元素; template struct HashTbPtrEle { public: HashTbPtrEle() : keyValue(0), pInnerPtr(NULL) {}; explicit HashTbPtrEle( unsigned int inKeyValue, T_Inner* pInPtr ) : keyValue(inKeyValue), pInnerPtr(pInPtr) {} ~HashTbPtrEle() {} public: ///取键值,hashtb需要; unsigned int GetKey() { return keyValue; } ///返回内部元素指针; T_Inner* GetInnerPtr() { return pInnerPtr; } private: unsigned int keyValue;//对应指针的键值; T_Inner* pInnerPtr; }; /* 简单的迭代器类,用于遍历DsDynaArr,便于代码替换,by dzj, 08.09.10; */ template struct DsDynArrIter { public: explicit DsDynArrIter( T_Owner& inOwner ) : innerOwner(&inOwner) {}; ~DsDynArrIter() {}; public: //操作符 DsDynArrIter& operator = ( const DsDynArrIter& inIter ) { if ( this != &inIter ) { arrPosValue = inIter.arrPosValue; vecPosValue = inIter.vecPosValue; innerOwner = inIter.innerOwner; } return *this; } //bool operator ==( const DsDynArrIter& inIter ) bool operator == ( const DsDynArrIter& inIter ) { return (arrPosValue == inIter.arrPosValue) && (vecPosValue == inIter.arrPosValue) && (innerOwner == inIter.innerOwner); } //bool operator !=( const DsDynArrIter& inIter ) bool operator != ( const DsDynArrIter& inIter ) { return (arrPosValue != inIter.arrPosValue) || (vecPosValue != inIter.vecPosValue) || (innerOwner != inIter.innerOwner); } DsDynArrIter& operator ++( int incValue ) { innerOwner->IncIterator( arrPosValue, vecPosValue ); return *this; }; public: //使用接口 T_OwnerEle* operator ->() { T_OwnerEle* found = NULL; if ( GetEleAtPos( arrPosValue, vecPosValue, found ) ) { return found; } else { return NULL; } } T_OwnerEle& operator *() { T_OwnerEle* found = NULL; innerOwner->GetEleAtPos( arrPosValue, vecPosValue, found ); return *found; } public: unsigned int arrPosValue;//数组位置; unsigned int vecPosValue;//后备vector位置; public: T_Owner* innerOwner; }; //template //bool operator < ( const DsDynArrIter& firstIter, DsDynArrIter& secondIter ) //{ // return (firstIter.arrPosValue < secondIter.arrPosValue) || // ( ( firstIter.arrPosValue == secondIter.arrPosValue ) && ( firstIter.vecPosValue < secondIter.vecPosValue ) ); //} /* 简单的动态数组,内部使用一个vector保存可能超出范围的存放元素 存放的元素必须实现unsigned int GetKey(),key值相同者,后存放的值覆盖之前存放的值; */ template struct DsDynaArr { public: ///////////////////////////////////////////////////////////////////////////////// ///实现内部遍历指针; typedef DsDynArrIter< DsDynaArr, T_Ele > iterator; iterator begin() { iterator tmpiter(*this); tmpiter.arrPosValue = 0; tmpiter.vecPosValue = 0; return tmpiter; }; iterator end() { iterator tmpiter(*this); tmpiter.arrPosValue = m_curPos; tmpiter.vecPosValue = (unsigned int) m_AssuArray.size(); return tmpiter; } bool IsEleValid( const iterator& inIter ) { if ( inIter.arrPosValue < m_curPos ) { return true; } else { if ( inIter.vecPosValue < (m_AssuArray.size()) ) { return true; } } return false; } bool GetEleAtPos( const unsigned int arrPosValue, const unsigned int vecPosValue, T_Ele*& outEle ) { if ( arrPosValue < m_curPos ) { outEle = &(m_innerArray[arrPosValue]); return true; } else { if ( vecPosValue < (m_AssuArray.size()) ) { outEle = &(m_AssuArray[vecPosValue]); return true; } } return false;//error, 传入位置越界; } bool IncIterator ( unsigned int& arrPosValue, unsigned int& vecPosValue ) { if ( arrPosValue < m_curPos ) { ++ (arrPosValue); return true; } else { if ( !m_AssuArray.empty() ) { if ( vecPosValue < m_AssuArray.size() ) { ++ (vecPosValue); return true; } } } return false; } ///实现内部遍历指针; ///////////////////////////////////////////////////////////////////////////////// ///构造、析构与初始化; public: DsDynaArr() { InitDynaArr(); } ~DsDynaArr() {}; void InitDynaArr( ) { m_curEleNum = 0; m_innerArrSize = initSize; m_curPos = 0; m_AssuArray.clear(); } ///操作接口; public: //加元素; void PushEle( T_Ele inEle ) { T_Ele* pTmpEle = FindEle( inEle.GetKey() ); if ( NULL != pTmpEle ) { //之前存在该元素,新值覆盖旧值; *pTmpEle = inEle; return; } //之前不存在该元素,push新值; if ( m_curPos < m_innerArrSize ) { //存放此元素后,当前位置不会越界; m_innerArray[m_curPos++] = inEle; } else { m_AssuArray.push_back( inEle ); } ++ m_curEleNum;//新增了一个元素; } //查找特定键值元素; T_Ele* FindEle( const unsigned int inKey ) { for ( unsigned int i=0; i::iterator iter=m_AssuArray.begin(); iter!=m_AssuArray.end(); ++iter ) { if ( inKey == iter->GetKey() ) { //找到对应键值元素; return &(*iter);//对应元素的地址; } } } return NULL;//两个地方都没找到,不存在指定键值元素; } //删除指定键值元素; bool DelEle( const unsigned int& inKey ) { if ( IsEmpty() ) { return false; } for ( unsigned int i=0; i::iterator iter=m_AssuArray.begin(); iter!=m_AssuArray.end(); ++iter ) { if ( inKey == iter->GetKey() ) { if ( &(*iter) != &(m_AssuArray.back()) ) { *iter = m_AssuArray.back();//把最后一个元素调至当前位置,同时移动当前位置把最后一个元素删掉; } m_AssuArray.pop_back(); --m_curEleNum;//减少了一个元素; isDel = true; break; } } if ( !m_AssuArray.empty() ) //后备vector中还有元素,尽量把这些元素移至数组; { unsigned curPos = m_curPos; for ( unsigned int i=curPos; i m_AssuArray;//如果m_innerArray放不下,则放此处; }; /* 简单的迭代器类,用于遍历DsHashTable,便于代码替换,by dzj, 08.09.10; */ template struct DsHashTbIter { public: explicit DsHashTbIter( T_Owner& inOwner ) : innerOwner(&inOwner), hashPos(0), eleIter(inOwner.GetFirstItem()) {}; ~DsHashTbIter() {}; public: //操作符 bool operator ==( const DsHashTbIter& inIter ) { return (hashPos == inIter.hashPos) && ( eleIter == inIter.eleIter ) && (innerOwner == inIter.innerOwner); } bool operator !=( const DsHashTbIter& inIter ) { return (hashPos != inIter.hashPos) || (eleIter != inIter.eleIter) || (innerOwner != inIter.innerOwner); } DsHashTbIter& operator ++( int incValue ) { innerOwner->IncIterator( hashPos, eleIter ); return *this; }; public: //使用接口 T_OwnerEle* operator ->() { T_OwnerEle* found = NULL; if ( GetEleAtPos( hashPos, eleIter, found ) ) { return found; } else { return NULL; } } T_OwnerEle& operator *() { T_OwnerEle* found = NULL; innerOwner->GetEleAtPos( hashPos, eleIter, found ); return *found; } public: unsigned int hashPos;//当前所遍历至的hash值; typename T_OwnerItem::iterator eleIter;//hash值对应表元素(自定义的动态数组)的迭代器; private: T_Owner* innerOwner; }; /* 简单hash表,T_Ele必须实现unsigned int GetKey(),同样键值只存储一个元素,新值覆盖旧值; push操作时间,常数 查找与pop时间,常数*(存储元素数/键值范围(内部表元素平均长度)),并与是否需要查找内部数组向量有关系 删除时间,约为查找时间的两倍,注:这一比率与stl::map相当; 模板参数原则: 1.hashRange尽量为可能存储元素的1/5以上; 2.innerArrSize*hashRange >= 2*可能储的元素数; 如果存储的元素数与hashRange相当(1/2至1/4),则查找速度将比stl::map快一个数量级(约10-20倍) 如果存储的元素数大大超出键值范围(10倍以上,即hashRange为存储元素数目的1/10或更小) ,则应该使用stl::map,因为stl::map对存储的元素数不敏感; */ #include template struct DsHashTable { public: ///////////////////////////////////////////////////////////////////////////////// ///实现内部遍历指针; typedef DsHashTbIter< DsHashTable/*自身类型*/, DsDynaArr/*表项类型*/, T_Ele/*元素类型*/ > iterator; iterator begin() { iterator tmpiter(*this); //返回:1、如果本表中存在有效元素,则返回第一个有效元素; // 2、如果没有有效元素,则返回值==end(); for ( unsigned int i=0; i::iterator& eleIter/*hash值对应表元素(自定义的动态数组)的迭代器*/ , T_Ele*& outEle ) { if ( ( hashPos < hashRange ) && ( m_innerArr[hashPos].IsEleValid( eleIter ) ) ) { return m_innerArr[hashPos].GetEleAtPos( eleIter.arrPosValue, eleIter.vecPosValue, outEle ); } return false;//error, 传入位置越界; } bool IncIterator ( unsigned int& hashPos/*当前所遍历至的hash值*/ , typename DsDynaArr::iterator& eleIter/*hash值对应表元素(自定义的动态数组)的迭代器*/ ) { if ( hashPos < hashRange ) { eleIter ++; if ( m_innerArr[hashPos].IsEleValid( eleIter ) ) { return true; } else { //当前hash值表已遍历完毕; unsigned int curHashPos = ++hashPos;//移至下一个hash值; for ( unsigned int i=curHashPos; i GetFirstItem() { return m_innerArr[0]; } void InitExplore() { m_expHashPos = 0; //当前遍历的hash表项; m_expDynArrArrPos = 0;//当前遍历的hash表项的内部数组位置; m_expDynArrVecPos = 0;//当前遍历的hash表项的内部vector位置; } typedef bool (*PFN_EXP_PROC)( T_Ele* pToBeExp, void* pParam ); void ExploreProcess( PFN_EXP_PROC expProc, void* pParam ) { InitExplore();//初始化遍历; if ( GetEleNum() <= 0 ) { return;//表中无元素; } T_Ele* pOut = NULL; for ( unsigned int i=0; i= hashRange ) { return NULL;//已经遍历到头了; } T_Ele* pOut = NULL; if ( m_innerArr[m_expHashPos].GetEleAtPos( m_expDynArrArrPos, m_expDynArrVecPos, pOut) ) { //在原遍历表项中找到了下一个有效元素; m_innerArr[m_expHashPos].IncIterator( m_expDynArrArrPos, m_expDynArrVecPos ); return pOut; } else { //之前的hash表项已遍历完毕; //找到下一个有效的hash表项,并重置3项; unsigned int curHashPos = m_expHashPos + 1;//移至下一个hash值; for ( unsigned int i=curHashPos; i::iterator iter = m_innerArr[0].begin(); iter != m_innerArr[0].end(); iter++ ) { T_Ele tmptest = *iter; } } unsigned int GetEleNum() { return m_curEleNum; } private: unsigned int m_curEleNum;//当前存放的元素个数; DsDynaArr m_innerArr[hashRange];//内部存放数组; ////added by dzj, 09.11.10,因为centersrv加副本管理后发现explore20480个元素的本容器太耗时,但如果使用类似dsepoll的多层bit又较麻烦,因此测下简单的bitset看是否更快点; //bitset m_validPos;//added by dzj, 09.11.10,因为centersrv加副本管理后发现explore20480个元素的本容器太耗时,但如果使用类似dsepoll的多层bit又较麻烦,因此测下简单的bitset看是否更快点; }; //template //struct DsOldHashVector //{ //public: // DsOldHashVector() {}; // ~DsOldHashVector() {}; // //public: // //插入新键值对,GetKey()值相同者,旧值覆盖新值; // void PushEle( T_Ele inEle ) // { // unsigned int hashValue = 0; // if ( !NumRegionHash( 0, hashRange-1, inEle.GetKey(), hashValue ) ) // { // return; // } // // T_Ele* pFound = NULL; // FindEle( inEle.GetKey(), pFound ); // if ( NULL != pFound ) // { // *pFound = inEle;//覆盖旧值; // return;//原来已有该元素; // } // // //原来无该元素,新加之; // m_innerVec[hashValue].push_back( inEle ); // } // // //寻找指定键值元素,成功执行时返回true(无论是否找到),否则返回false; // bool FindEle( const unsigned int& inKey, T_Ele*& pOutEle ) // { // pOutEle = NULL; // unsigned int hashValue = 0; // bool ishashok = NumRegionHash( 0, hashRange-1, inKey, hashValue ); // if ( !ishashok ) // { // return false; // } // // if ( m_innerVec[hashValue].empty() ) // { // //没有对应输入键值的元素; // pOutEle = NULL; // return false; // } // // vector* findVec = &(m_innerVec[hashValue]); // for ( typename vector::iterator iter = findVec->begin(); // iter != findVec->end(); ++iter ) // { // if ( inKey == iter->GetKey() ) // { // //找到对应键值元素; // pOutEle = &(*iter);//对应元素的地址; // return true; // } // } // // pOutEle = NULL;//没找到; // return true; // // } // //private: // vector m_innerVec[hashRange];//内部存放数组; //};