SNAP Library, Developer Reference
2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
|
00001 00002 // Hash-Table-Key-Data 00003 #pragma pack(push, 1) // pack class size 00004 template <class TKey, class TDat> 00005 class THashKeyDat{ 00006 public: 00007 TInt Next; 00008 TInt HashCd; 00009 TKey Key; 00010 TDat Dat; 00011 public: 00012 THashKeyDat(): 00013 Next(-1), HashCd(-1), Key(), Dat(){} 00014 THashKeyDat(const int& _Next, const int& _HashCd, const TKey& _Key): 00015 Next(_Next), HashCd(_HashCd), Key(_Key), Dat(){} 00016 explicit THashKeyDat(TSIn& SIn): 00017 Next(SIn), HashCd(SIn), Key(SIn), Dat(SIn){} 00018 void Save(TSOut& SOut) const { 00019 Next.Save(SOut); HashCd.Save(SOut); Key.Save(SOut); Dat.Save(SOut);} 00020 void LoadXml(const PXmlTok& XmlTok, const TStr& Nm=""); 00021 void SaveXml(TSOut& SOut, const TStr& Nm) const; 00022 00023 bool operator==(const THashKeyDat& HashKeyDat) const { 00024 if (this==&HashKeyDat || (HashCd==HashKeyDat.HashCd 00025 && Key==HashKeyDat.Key && Dat==HashKeyDat.Dat)){return true;} 00026 return false;} 00027 THashKeyDat& operator=(const THashKeyDat& HashKeyDat){ 00028 if (this!=&HashKeyDat){ 00029 Next=HashKeyDat.Next; HashCd=HashKeyDat.HashCd; 00030 Key=HashKeyDat.Key; Dat=HashKeyDat.Dat;} 00031 return *this;} 00032 }; 00033 #pragma pack(pop) 00034 00036 // Hash-Table-Key-Data-Iterator 00037 template<class TKey, class TDat> 00038 class THashKeyDatI{ 00039 private: 00040 typedef THashKeyDat<TKey, TDat> THKeyDat; 00041 THKeyDat* KeyDatI; 00042 THKeyDat* EndI; 00043 public: 00044 THashKeyDatI(): KeyDatI(NULL), EndI(NULL){} 00045 THashKeyDatI(const THashKeyDatI& _HashKeyDatI): 00046 KeyDatI(_HashKeyDatI.KeyDatI), EndI(_HashKeyDatI.EndI){} 00047 THashKeyDatI(const THKeyDat* _KeyDatI, const THKeyDat* _EndI): 00048 KeyDatI((THKeyDat*)_KeyDatI), EndI((THKeyDat*)_EndI){} 00049 00050 THashKeyDatI& operator=(const THashKeyDatI& HashKeyDatI){ 00051 KeyDatI=HashKeyDatI.KeyDatI; EndI=HashKeyDatI.EndI; return *this;} 00052 bool operator==(const THashKeyDatI& HashKeyDatI) const { 00053 return KeyDatI==HashKeyDatI.KeyDatI;} 00054 bool operator<(const THashKeyDatI& HashKeyDatI) const { 00055 return KeyDatI<HashKeyDatI.KeyDatI;} 00056 THashKeyDatI& operator++(int){ KeyDatI++; while (KeyDatI < EndI && KeyDatI->HashCd==-1) { KeyDatI++; } return *this; } 00057 THashKeyDatI& operator--(int){ do { KeyDatI--; } while (KeyDatI->HashCd==-1); return *this;} 00058 00059 THKeyDat& operator*() const { return *KeyDatI; } 00060 THKeyDat& operator()() const { return *KeyDatI; } 00061 THKeyDat* operator->() const { return KeyDatI; } 00062 00064 bool IsEmpty() const { return KeyDatI == NULL; } 00066 bool IsEnd() const { return EndI == KeyDatI; } 00067 00068 const TKey& GetKey() const {Assert((KeyDatI!=NULL)&&(KeyDatI->HashCd!=-1)); return KeyDatI->Key;} 00069 const TDat& GetDat() const {Assert((KeyDatI!=NULL)&&(KeyDatI->HashCd!=-1)); return KeyDatI->Dat;} 00070 TDat& GetDat() {Assert((KeyDatI!=NULL)&&(KeyDatI->HashCd!=-1)); return KeyDatI->Dat;} 00071 }; 00072 00074 // Default-Hash-Function 00075 template<class TKey> 00076 class TDefaultHashFunc { 00077 public: 00078 static inline int GetPrimHashCd(const TKey& Key) { return Key.GetPrimHashCd(); } 00079 static inline int GetSecHashCd(const TKey& Key) { return Key.GetSecHashCd(); } 00080 }; 00081 00083 // Hash-Table 00084 template<class TKey, class TDat, class THashFunc = TDefaultHashFunc<TKey> > 00085 class THash{ 00086 public: 00087 enum {HashPrimes=32}; 00088 static const unsigned int HashPrimeT[HashPrimes]; 00089 public: 00090 typedef THashKeyDatI<TKey, TDat> TIter; 00091 private: 00092 typedef THashKeyDat<TKey, TDat> THKeyDat; 00093 typedef TPair<TKey, TDat> TKeyDatP; 00094 TIntV PortV; 00095 TVec<THKeyDat> KeyDatV; 00096 TBool AutoSizeP; 00097 TInt FFreeKeyId, FreeKeys; 00098 private: 00099 class THashKeyDatCmp { 00100 public: 00101 const THash<TKey, TDat, THashFunc>& Hash; 00102 bool CmpKey, Asc; 00103 THashKeyDatCmp(THash<TKey, TDat, THashFunc>& _Hash, const bool& _CmpKey, const bool& _Asc) : 00104 Hash(_Hash), CmpKey(_CmpKey), Asc(_Asc) { } 00105 bool operator () (const int& KeyId1, const int& KeyId2) const { 00106 if (CmpKey) { 00107 if (Asc) { return Hash.GetKey(KeyId1) < Hash.GetKey(KeyId2); } 00108 else { return Hash.GetKey(KeyId2) < Hash.GetKey(KeyId1); } } 00109 else { 00110 if (Asc) { return Hash[KeyId1] < Hash[KeyId2]; } 00111 else { return Hash[KeyId2] < Hash[KeyId1]; } } } 00112 }; 00113 private: 00114 THKeyDat& GetHashKeyDat(const int& KeyId){ 00115 THKeyDat& KeyDat=KeyDatV[KeyId]; 00116 Assert(KeyDat.HashCd!=-1); return KeyDat;} 00117 const THKeyDat& GetHashKeyDat(const int& KeyId) const { 00118 const THKeyDat& KeyDat=KeyDatV[KeyId]; 00119 Assert(KeyDat.HashCd!=-1); return KeyDat;} 00120 uint GetNextPrime(const uint& Val) const; 00121 void Resize(); 00122 public: 00123 THash(): 00124 PortV(), KeyDatV(), 00125 AutoSizeP(true), FFreeKeyId(-1), FreeKeys(0){} 00126 THash(const THash& Hash): 00127 PortV(Hash.PortV), KeyDatV(Hash.KeyDatV), AutoSizeP(Hash.AutoSizeP), 00128 FFreeKeyId(Hash.FFreeKeyId), FreeKeys(Hash.FreeKeys){} 00129 explicit THash(const int& ExpectVals, const bool& _AutoSizeP=false); 00130 explicit THash(TSIn& SIn): 00131 PortV(SIn), KeyDatV(SIn), 00132 AutoSizeP(SIn), FFreeKeyId(SIn), FreeKeys(SIn){ 00133 SIn.LoadCs();} 00134 void Load(TSIn& SIn){ 00135 PortV.Load(SIn); KeyDatV.Load(SIn); 00136 AutoSizeP=TBool(SIn); FFreeKeyId=TInt(SIn); FreeKeys=TInt(SIn); 00137 SIn.LoadCs();} 00138 void Save(TSOut& SOut) const { 00139 PortV.Save(SOut); KeyDatV.Save(SOut); 00140 AutoSizeP.Save(SOut); FFreeKeyId.Save(SOut); FreeKeys.Save(SOut); 00141 SOut.SaveCs();} 00142 void LoadXml(const PXmlTok& XmlTok, const TStr& Nm=""); 00143 void SaveXml(TSOut& SOut, const TStr& Nm); 00144 00145 THash& operator=(const THash& Hash){ 00146 if (this!=&Hash){ 00147 PortV=Hash.PortV; KeyDatV=Hash.KeyDatV; AutoSizeP=Hash.AutoSizeP; 00148 FFreeKeyId=Hash.FFreeKeyId; FreeKeys=Hash.FreeKeys;} 00149 return *this;} 00150 bool operator==(const THash& Hash) const; //J: zdaj tak kot je treba 00151 bool operator < (const THash& Hash) const { Fail; return true; } 00152 const TDat& operator[](const int& KeyId) const {return GetHashKeyDat(KeyId).Dat;} 00153 TDat& operator[](const int& KeyId){return GetHashKeyDat(KeyId).Dat;} 00154 TDat& operator()(const TKey& Key){return AddDat(Key);} 00155 ::TSize GetMemUsed() const { 00156 // return PortV.GetMemUsed()+KeyDatV.GetMemUsed()+sizeof(bool)+2*sizeof(int);} 00157 int64 MemUsed = sizeof(bool)+2*sizeof(int); 00158 MemUsed += int64(PortV.Reserved()) * int64(sizeof(TInt)); 00159 for (int KeyDatN = 0; KeyDatN < KeyDatV.Len(); KeyDatN++) { 00160 MemUsed += int64(2 * sizeof(TInt)); 00161 MemUsed += int64(KeyDatV[KeyDatN].Key.GetMemUsed()); 00162 MemUsed += int64(KeyDatV[KeyDatN].Dat.GetMemUsed()); 00163 } 00164 return ::TSize(MemUsed); 00165 } 00166 00167 TIter BegI() const { 00168 if (Len() == 0){return TIter(KeyDatV.EndI(), KeyDatV.EndI());} 00169 if (IsKeyIdEqKeyN()) { return TIter(KeyDatV.BegI(), KeyDatV.EndI());} 00170 int FKeyId=-1; FNextKeyId(FKeyId); 00171 return TIter(KeyDatV.BegI()+FKeyId, KeyDatV.EndI()); } 00172 TIter EndI() const {return TIter(KeyDatV.EndI(), KeyDatV.EndI());} 00173 //TIter GetI(const int& KeyId) const {return TIter(&KeyDatV[KeyId], KeyDatV.EndI());} 00174 TIter GetI(const TKey& Key) const {return TIter(&KeyDatV[GetKeyId(Key)], KeyDatV.EndI());} 00175 00176 void Gen(const int& ExpectVals){ 00177 PortV.Gen(GetNextPrime(ExpectVals/2)); KeyDatV.Gen(ExpectVals, 0); 00178 FFreeKeyId=-1; FreeKeys=0; PortV.PutAll(TInt(-1));} 00179 00180 void Clr(const bool& DoDel=true, const int& NoDelLim=-1, const bool& ResetDat=true); 00181 bool Empty() const {return Len()==0;} 00182 int Len() const {return KeyDatV.Len()-FreeKeys;} 00183 int GetPorts() const {return PortV.Len();} 00184 bool IsAutoSize() const {return AutoSizeP;} 00185 int GetMxKeyIds() const {return KeyDatV.Len();} 00186 int GetReservedKeyIds() const {return KeyDatV.Reserved();} 00187 bool IsKeyIdEqKeyN() const {return FreeKeys==0;} 00188 00189 int AddKey(const TKey& Key); 00190 TDat& AddDatId(const TKey& Key){ 00191 int KeyId=AddKey(Key); return KeyDatV[KeyId].Dat=KeyId;} 00192 TDat& AddDat(const TKey& Key){return KeyDatV[AddKey(Key)].Dat;} 00193 TDat& AddDat(const TKey& Key, const TDat& Dat){ 00194 return KeyDatV[AddKey(Key)].Dat=Dat;} 00195 00196 void DelKey(const TKey& Key); 00197 void DelIfKey(const TKey& Key){ 00198 int KeyId; if (IsKey(Key, KeyId)){DelKeyId(KeyId);}} 00199 void DelKeyId(const int& KeyId){DelKey(GetKey(KeyId));} 00200 void DelKeyIdV(const TIntV& KeyIdV){ 00201 for (int KeyIdN=0; KeyIdN<KeyIdV.Len(); KeyIdN++){DelKeyId(KeyIdV[KeyIdN]);}} 00202 00203 void MarkDelKey(const TKey& Key); // marks the record as deleted - doesn't delete Dat (to avoid fragmentation) 00204 void MarkDelKeyId(const int& KeyId){MarkDelKey(GetKey(KeyId));} 00205 00206 const TKey& GetKey(const int& KeyId) const { return GetHashKeyDat(KeyId).Key;} 00207 int GetKeyId(const TKey& Key) const; 00209 int GetRndKeyId(TRnd& Rnd) const; 00211 int GetRndKeyId(TRnd& Rnd, const double& EmptyFrac); 00212 bool IsKey(const TKey& Key) const {return GetKeyId(Key)!=-1;} 00213 bool IsKey(const TKey& Key, int& KeyId) const { KeyId=GetKeyId(Key); return KeyId!=-1;} 00214 bool IsKeyId(const int& KeyId) const { 00215 return (0<=KeyId)&&(KeyId<KeyDatV.Len())&&(KeyDatV[KeyId].HashCd!=-1);} 00216 const TDat& GetDat(const TKey& Key) const {return KeyDatV[GetKeyId(Key)].Dat;} 00217 TDat& GetDat(const TKey& Key){return KeyDatV[GetKeyId(Key)].Dat;} 00218 // TKeyDatP GetKeyDat(const int& KeyId) const { 00219 // TKeyDat& KeyDat=GetHashKeyDat(KeyId); 00220 // return TKeyDatP(KeyDat.Key, KeyDat.Dat);} 00221 void GetKeyDat(const int& KeyId, TKey& Key, TDat& Dat) const { 00222 const THKeyDat& KeyDat=GetHashKeyDat(KeyId); 00223 Key=KeyDat.Key; Dat=KeyDat.Dat;} 00224 bool IsKeyGetDat(const TKey& Key, TDat& Dat) const {int KeyId; 00225 if (IsKey(Key, KeyId)){Dat=GetHashKeyDat(KeyId).Dat; return true;} 00226 else {return false;}} 00227 00228 int FFirstKeyId() const {return 0-1;} 00229 bool FNextKeyId(int& KeyId) const; 00230 void GetKeyV(TVec<TKey>& KeyV) const; 00231 void GetDatV(TVec<TDat>& DatV) const; 00232 void GetKeyDatPrV(TVec<TPair<TKey, TDat> >& KeyDatPrV) const; 00233 void GetDatKeyPrV(TVec<TPair<TDat, TKey> >& DatKeyPrV) const; 00234 void GetKeyDatKdV(TVec<TKeyDat<TKey, TDat> >& KeyDatKdV) const; 00235 void GetDatKeyKdV(TVec<TKeyDat<TDat, TKey> >& DatKeyKdV) const; 00236 00237 void Swap(THash& Hash); 00238 void Defrag(); 00239 void Pack(){KeyDatV.Pack();} 00240 void Sort(const bool& CmpKey, const bool& Asc); 00241 void SortByKey(const bool& Asc=true) { Sort(true, Asc); } 00242 void SortByDat(const bool& Asc=true) { Sort(false, Asc); } 00243 }; 00244 00245 template<class TKey, class TDat, class THashFunc> 00246 const unsigned int THash<TKey, TDat, THashFunc>::HashPrimeT[HashPrimes]={ 00247 3ul, 5ul, 11ul, 23ul, 00248 53ul, 97ul, 193ul, 389ul, 769ul, 00249 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, 00250 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 00251 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 00252 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, 00253 1610612741ul, 3221225473ul, 4294967291ul 00254 }; 00255 00256 template<class TKey, class TDat, class THashFunc> 00257 uint THash<TKey, TDat, THashFunc>::GetNextPrime(const uint& Val) const { 00258 const uint* f=(const uint*)HashPrimeT, *m, *l=(const uint*)HashPrimeT + (int)HashPrimes; 00259 int h, len = (int)HashPrimes; 00260 while (len > 0) { 00261 h = len >> 1; m = f + h; 00262 if (*m < Val) { f = m; f++; len = len - h - 1; } 00263 else len = h; 00264 } 00265 return f == l ? *(l - 1) : *f; 00266 } 00267 00268 template<class TKey, class TDat, class THashFunc> 00269 void THash<TKey, TDat, THashFunc>::Resize(){ 00270 // resize & initialize port vector 00271 //if (PortV.Len()==0){PortV.Gen(17);} 00272 //else {PortV.Gen(2*PortV.Len()+1);} 00273 if (PortV.Len()==0){ 00274 PortV.Gen(17); 00275 } else if (AutoSizeP&&(KeyDatV.Len()>2*PortV.Len())){ 00276 PortV.Gen(GetNextPrime(PortV.Len()+1)); 00277 } else { 00278 return; 00279 } 00280 PortV.PutAll(TInt(-1)); 00281 // rehash keys 00282 for (int KeyId=0; KeyId<KeyDatV.Len(); KeyId++){ 00283 THKeyDat& KeyDat=KeyDatV[KeyId]; 00284 if (KeyDat.HashCd!=-1){ 00285 const int PortN = abs(THashFunc::GetPrimHashCd(KeyDat.Key) % PortV.Len()); 00286 KeyDat.Next=PortV[PortN]; 00287 PortV[PortN]=KeyId; 00288 } 00289 } 00290 } 00291 00292 template<class TKey, class TDat, class THashFunc> 00293 THash<TKey, TDat, THashFunc>::THash(const int& ExpectVals, const bool& _AutoSizeP): 00294 PortV(GetNextPrime(ExpectVals/2)), KeyDatV(ExpectVals, 0), 00295 AutoSizeP(_AutoSizeP), FFreeKeyId(-1), FreeKeys(0){ 00296 PortV.PutAll(TInt(-1)); 00297 } 00298 00299 template<class TKey, class TDat, class THashFunc> 00300 bool THash<TKey, TDat, THashFunc>::operator==(const THash& Hash) const { 00301 if (Len() != Hash.Len()) { return false; } 00302 for (int i = FFirstKeyId(); FNextKeyId(i); ) { 00303 const TKey& Key = GetKey(i); 00304 if (! Hash.IsKey(Key)) { return false; } 00305 if (GetDat(Key) != Hash.GetDat(Key)) { return false; } 00306 } 00307 return true; 00308 } 00309 00310 template<class TKey, class TDat, class THashFunc> 00311 void THash<TKey, TDat, THashFunc>::Clr(const bool& DoDel, const int& NoDelLim, const bool& ResetDat){ 00312 if (DoDel){ 00313 PortV.Clr(); KeyDatV.Clr(); 00314 } else { 00315 PortV.PutAll(TInt(-1)); 00316 KeyDatV.Clr(DoDel, NoDelLim); 00317 if (ResetDat){KeyDatV.PutAll(THKeyDat());} 00318 } 00319 FFreeKeyId=TInt(-1); FreeKeys=TInt(0); 00320 } 00321 00322 template<class TKey, class TDat, class THashFunc> 00323 int THash<TKey, TDat, THashFunc>::AddKey(const TKey& Key){ 00324 if ((KeyDatV.Len()>2*PortV.Len())||PortV.Empty()){Resize();} 00325 const int PortN=abs(THashFunc::GetPrimHashCd(Key)%PortV.Len()); 00326 const int HashCd=abs(THashFunc::GetSecHashCd(Key)); 00327 int PrevKeyId=-1; 00328 int KeyId=PortV[PortN]; 00329 while ((KeyId!=-1) && 00330 !((KeyDatV[KeyId].HashCd==HashCd) && (KeyDatV[KeyId].Key==Key))){ 00331 PrevKeyId=KeyId; KeyId=KeyDatV[KeyId].Next;} 00332 00333 if (KeyId==-1){ 00334 if (FFreeKeyId==-1){ 00335 KeyId=KeyDatV.Add(THKeyDat(-1, HashCd, Key)); 00336 } else { 00337 KeyId=FFreeKeyId; FFreeKeyId=KeyDatV[FFreeKeyId].Next; FreeKeys--; 00338 //KeyDatV[KeyId]=TKeyDat(-1, HashCd, Key); // slow version 00339 KeyDatV[KeyId].Next=-1; 00340 KeyDatV[KeyId].HashCd=HashCd; 00341 KeyDatV[KeyId].Key=Key; 00342 //KeyDatV[KeyId].Dat=TDat(); // already empty 00343 } 00344 if (PrevKeyId==-1){ 00345 PortV[PortN]=KeyId; 00346 } else { 00347 KeyDatV[PrevKeyId].Next=KeyId; 00348 } 00349 } 00350 return KeyId; 00351 } 00352 00353 template<class TKey, class TDat, class THashFunc> 00354 void THash<TKey, TDat, THashFunc>::DelKey(const TKey& Key){ 00355 IAssert(!PortV.Empty()); 00356 const int PortN=abs(THashFunc::GetPrimHashCd(Key)%PortV.Len()); 00357 const int HashCd=abs(THashFunc::GetSecHashCd(Key)); 00358 int PrevKeyId=-1; 00359 int KeyId=PortV[PortN]; 00360 00361 while ((KeyId!=-1) && 00362 !((KeyDatV[KeyId].HashCd==HashCd) && (KeyDatV[KeyId].Key==Key))){ 00363 PrevKeyId=KeyId; KeyId=KeyDatV[KeyId].Next;} 00364 00365 //IAssertR(KeyId!=-1, Key.GetStr()); //J: vsi razredi nimajo nujno funkcije GetStr()? 00366 IAssert(KeyId!=-1); //J: vsi razredi nimajo nujno funkcije GetStr()? 00367 if (PrevKeyId==-1){PortV[PortN]=KeyDatV[KeyId].Next;} 00368 else {KeyDatV[PrevKeyId].Next=KeyDatV[KeyId].Next;} 00369 KeyDatV[KeyId].Next=FFreeKeyId; FFreeKeyId=KeyId; FreeKeys++; 00370 KeyDatV[KeyId].HashCd=TInt(-1); 00371 KeyDatV[KeyId].Key=TKey(); 00372 KeyDatV[KeyId].Dat=TDat(); 00373 } 00374 00375 template<class TKey, class TDat, class THashFunc> 00376 void THash<TKey, TDat, THashFunc>::MarkDelKey(const TKey& Key){ 00377 // MarkDelKey is same as Delkey expect last two lines 00378 IAssert(!PortV.Empty()); 00379 const int PortN=abs(THashFunc::GetPrimHashCd(Key)%PortV.Len()); 00380 const int HashCd=abs(THashFunc::GetSecHashCd(Key)); 00381 int PrevKeyId=-1; 00382 int KeyId=PortV[PortN]; 00383 while ((KeyId!=-1) && 00384 !((KeyDatV[KeyId].HashCd==HashCd) && (KeyDatV[KeyId].Key==Key))){ 00385 PrevKeyId=KeyId; KeyId=KeyDatV[KeyId].Next;} 00386 IAssertR(KeyId!=-1, Key.GetStr()); 00387 if (PrevKeyId==-1){PortV[PortN]=KeyDatV[KeyId].Next;} 00388 else {KeyDatV[PrevKeyId].Next=KeyDatV[KeyId].Next;} 00389 KeyDatV[KeyId].Next=FFreeKeyId; FFreeKeyId=KeyId; FreeKeys++; 00390 KeyDatV[KeyId].HashCd=TInt(-1); 00391 } 00392 00393 template<class TKey, class TDat, class THashFunc> 00394 int THash<TKey, TDat, THashFunc>::GetRndKeyId(TRnd& Rnd) const { 00395 IAssert(! Empty()); 00396 int KeyId = abs(Rnd.GetUniDevInt(KeyDatV.Len())); 00397 while (KeyDatV[KeyId].HashCd == -1) { // if the index is empty, just try again 00398 KeyId = abs(Rnd.GetUniDevInt(KeyDatV.Len())); } 00399 return KeyId; 00400 } 00401 00402 // return random KeyId even if the hash table contains deleted keys 00403 // defrags the table if necessary 00404 template<class TKey, class TDat, class THashFunc> 00405 int THash<TKey, TDat, THashFunc>::GetRndKeyId(TRnd& Rnd, const double& EmptyFrac) { 00406 IAssert(! Empty()); 00407 if (FreeKeys/double(Len()+FreeKeys) > EmptyFrac) { Defrag(); } 00408 int KeyId = Rnd.GetUniDevInt(KeyDatV.Len()); 00409 while (KeyDatV[KeyId].HashCd == -1) { // if the index is empty, just try again 00410 KeyId = Rnd.GetUniDevInt(KeyDatV.Len()); 00411 } 00412 return KeyId; 00413 } 00414 00415 template<class TKey, class TDat, class THashFunc> 00416 int THash<TKey, TDat, THashFunc>::GetKeyId(const TKey& Key) const { 00417 if (PortV.Empty()){return -1;} 00418 const int PortN=abs(THashFunc::GetPrimHashCd(Key)%PortV.Len()); 00419 const int HashCd=abs(THashFunc::GetSecHashCd(Key)); 00420 int KeyId=PortV[PortN]; 00421 while ((KeyId!=-1) && 00422 !((KeyDatV[KeyId].HashCd==HashCd) && (KeyDatV[KeyId].Key==Key))){ 00423 KeyId=KeyDatV[KeyId].Next;} 00424 return KeyId; 00425 } 00426 00427 template<class TKey, class TDat, class THashFunc> 00428 bool THash<TKey, TDat, THashFunc>::FNextKeyId(int& KeyId) const { 00429 do {KeyId++;} while ((KeyId<KeyDatV.Len())&&(KeyDatV[KeyId].HashCd==-1)); 00430 return KeyId<KeyDatV.Len(); 00431 } 00432 00433 template<class TKey, class TDat, class THashFunc> 00434 void THash<TKey, TDat, THashFunc>::GetKeyV(TVec<TKey>& KeyV) const { 00435 KeyV.Gen(Len(), 0); 00436 int KeyId=FFirstKeyId(); 00437 while (FNextKeyId(KeyId)){ 00438 KeyV.Add(GetKey(KeyId));} 00439 } 00440 00441 template<class TKey, class TDat, class THashFunc> 00442 void THash<TKey, TDat, THashFunc>::GetDatV(TVec<TDat>& DatV) const { 00443 DatV.Gen(Len(), 0); 00444 int KeyId=FFirstKeyId(); 00445 while (FNextKeyId(KeyId)){ 00446 DatV.Add(GetHashKeyDat(KeyId).Dat);} 00447 } 00448 00449 template<class TKey, class TDat, class THashFunc> 00450 void THash<TKey, TDat, THashFunc>::GetKeyDatPrV(TVec<TPair<TKey, TDat> >& KeyDatPrV) const { 00451 KeyDatPrV.Gen(Len(), 0); 00452 TKey Key; TDat Dat; 00453 int KeyId=FFirstKeyId(); 00454 while (FNextKeyId(KeyId)){ 00455 GetKeyDat(KeyId, Key, Dat); 00456 KeyDatPrV.Add(TPair<TKey, TDat>(Key, Dat)); 00457 } 00458 } 00459 00460 template<class TKey, class TDat, class THashFunc> 00461 void THash<TKey, TDat, THashFunc>::GetDatKeyPrV(TVec<TPair<TDat, TKey> >& DatKeyPrV) const { 00462 DatKeyPrV.Gen(Len(), 0); 00463 TKey Key; TDat Dat; 00464 int KeyId=FFirstKeyId(); 00465 while (FNextKeyId(KeyId)){ 00466 GetKeyDat(KeyId, Key, Dat); 00467 DatKeyPrV.Add(TPair<TDat, TKey>(Dat, Key)); 00468 } 00469 } 00470 00471 template<class TKey, class TDat, class THashFunc> 00472 void THash<TKey, TDat, THashFunc>::GetKeyDatKdV(TVec<TKeyDat<TKey, TDat> >& KeyDatKdV) const { 00473 KeyDatKdV.Gen(Len(), 0); 00474 TKey Key; TDat Dat; 00475 int KeyId=FFirstKeyId(); 00476 while (FNextKeyId(KeyId)){ 00477 GetKeyDat(KeyId, Key, Dat); 00478 KeyDatKdV.Add(TKeyDat<TKey, TDat>(Key, Dat)); 00479 } 00480 } 00481 00482 template<class TKey, class TDat, class THashFunc> 00483 void THash<TKey, TDat, THashFunc>::GetDatKeyKdV(TVec<TKeyDat<TDat, TKey> >& DatKeyKdV) const { 00484 DatKeyKdV.Gen(Len(), 0); 00485 TKey Key; TDat Dat; 00486 int KeyId=FFirstKeyId(); 00487 while (FNextKeyId(KeyId)){ 00488 GetKeyDat(KeyId, Key, Dat); 00489 DatKeyKdV.Add(TKeyDat<TDat, TKey>(Dat, Key)); 00490 } 00491 } 00492 00493 template<class TKey, class TDat, class THashFunc> 00494 void THash<TKey, TDat, THashFunc>::Swap(THash& Hash) { 00495 if (this!=&Hash){ 00496 PortV.Swap(Hash.PortV); 00497 KeyDatV.Swap(Hash.KeyDatV); 00498 ::Swap(AutoSizeP, Hash.AutoSizeP); 00499 ::Swap(FFreeKeyId, Hash.FFreeKeyId); 00500 ::Swap(FreeKeys, Hash.FreeKeys); 00501 } 00502 } 00503 00504 template<class TKey, class TDat, class THashFunc> 00505 void THash<TKey, TDat, THashFunc>::Defrag(){ 00506 if (!IsKeyIdEqKeyN()){ 00507 THash<TKey, TDat, THashFunc> Hash(PortV.Len()); 00508 int KeyId=FFirstKeyId(); TKey Key; TDat Dat; 00509 while (FNextKeyId(KeyId)){ 00510 GetKeyDat(KeyId, Key, Dat); 00511 Hash.AddDat(Key, Dat); 00512 } 00513 Pack(); 00514 operator=(Hash); 00515 IAssert(IsKeyIdEqKeyN()); 00516 } 00517 } 00518 00519 template<class TKey, class TDat, class THashFunc> 00520 void THash<TKey, TDat, THashFunc>::Sort(const bool& CmpKey, const bool& Asc) { 00521 IAssertR(IsKeyIdEqKeyN(), "THash::Sort only works when table has no deleted keys."); 00522 TIntV TargV(Len()), MapV(Len()), StateV(Len()); 00523 for (int i = 0; i < TargV.Len(); i++) { 00524 TargV[i] = i; MapV[i] = i; StateV[i] = i; 00525 } 00526 // sort KeyIds 00527 THashKeyDatCmp HashCmp(*this, CmpKey, Asc); 00528 TargV.SortCmp(HashCmp); 00529 // now sort the update vector 00530 THashKeyDat<TKey, TDat> Tmp; 00531 for (int i = 0; i < TargV.Len()-1; i++) { 00532 const int SrcPos = MapV[TargV[i]]; 00533 const int Loc = i; 00534 // swap data 00535 Tmp = KeyDatV[SrcPos]; 00536 KeyDatV[SrcPos] = KeyDatV[Loc]; 00537 KeyDatV[Loc] = Tmp; 00538 // swap keys 00539 MapV[StateV[i]] = SrcPos; 00540 StateV.Swap(Loc, SrcPos); 00541 } 00542 for (int i = 0; i < TargV.Len(); i++) { 00543 MapV[TargV[i]] = i; } 00544 for (int p = 0; p < PortV.Len(); p++) { 00545 if (PortV[p] != -1) { 00546 PortV[p] = MapV[PortV[p]]; } } 00547 for (int i = 0; i < KeyDatV.Len(); i++) { 00548 if (KeyDatV[i].Next != -1) { 00549 KeyDatV[i].Next = MapV[KeyDatV[i].Next]; } 00550 } 00551 } 00552 00554 // Common-Hash-Types 00555 typedef THash<TCh, TCh> TChChH; 00556 typedef THash<TChTr, TInt> TChTrIntH; 00557 typedef THash<TInt, TInt> TIntH; 00558 typedef THash<TUInt64, TInt> TUInt64H; 00559 typedef THash<TInt, TBool> TIntBoolH; 00560 typedef THash<TInt, TInt> TIntIntH; 00561 typedef THash<TInt, TUInt64> TIntUInt64H; 00562 typedef THash<TInt, TIntFltPr> TIntIntFltPrH; 00563 typedef THash<TInt, TIntV> TIntIntVH; 00564 typedef THash<TInt, TIntH> TIntIntHH; 00565 typedef THash<TInt, TFlt> TIntFltH; 00566 typedef THash<TInt, TFltPr> TIntFltPrH; 00567 typedef THash<TInt, TFltTr> TIntFltTrH; 00568 typedef THash<TInt, TFltV> TIntFltVH; 00569 typedef THash<TInt, TStr> TIntStrH; 00570 typedef THash<TInt, TStrV> TIntStrVH; 00571 typedef THash<TInt, TIntPr> TIntIntPrH; 00572 typedef THash<TInt, TIntPrV> TIntIntPrVH; 00573 typedef THash<TUInt64, TStrV> TUInt64StrVH; 00574 typedef THash<TIntPr, TInt> TIntPrIntH; 00575 typedef THash<TIntPr, TIntV> TIntPrIntVH; 00576 typedef THash<TIntPr, TIntPrV> TIntPrIntPrVH; 00577 typedef THash<TIntTr, TInt> TIntTrIntH; 00578 typedef THash<TIntV, TInt> TIntVIntH; 00579 typedef THash<TUInt, TUInt> TUIntH; 00580 typedef THash<TIntPr, TInt> TIntPrIntH; 00581 typedef THash<TIntPr, TIntV> TIntPrIntVH; 00582 typedef THash<TIntPr, TFlt> TIntPrFltH; 00583 typedef THash<TIntTr, TFlt> TIntTrFltH; 00584 typedef THash<TIntPr, TStr> TIntPrStrH; 00585 typedef THash<TIntPr, TStrV> TIntPrStrVH; 00586 typedef THash<TIntStrPr, TInt> TIntStrPrIntH; 00587 typedef THash<TFlt, TFlt> TFltFltH; 00588 typedef THash<TStr, TInt> TStrH; 00589 typedef THash<TStr, TBool> TStrBoolH; 00590 typedef THash<TStr, TInt> TStrIntH; 00591 typedef THash<TStr, TIntPr> TStrIntPrH; 00592 typedef THash<TStr, TIntV> TStrIntVH; 00593 typedef THash<TStr, TUInt64V> TStrUInt64VH; 00594 typedef THash<TStr, TIntPrV> TStrIntPrVH; 00595 typedef THash<TStr, TFlt> TStrFltH; 00596 typedef THash<TStr, TFltV> TStrFltVH; 00597 typedef THash<TStr, TStr> TStrStrH; 00598 typedef THash<TStr, TStrPr> TStrStrPrH; 00599 typedef THash<TStr, TStrV> TStrStrVH; 00600 typedef THash<TStr, TStrPrV> TStrStrPrVH; 00601 typedef THash<TStr, TStrKdV> TStrStrKdVH; 00602 typedef THash<TStr, TIntFltPr> TStrIntFltPrH; 00603 typedef THash<TStr, TStrIntPrV> TStrStrIntPrVH; 00604 typedef THash<TStr, TStrIntKdV> TStrStrIntKdVH; 00605 typedef THash<TDbStr, TInt> TDbStrIntH; 00606 typedef THash<TDbStr, TStr> TDbStrStrH; 00607 typedef THash<TStrPr, TBool> TStrPrBoolH; 00608 typedef THash<TStrPr, TInt> TStrPrIntH; 00609 typedef THash<TStrPr, TFlt> TStrPrFltH; 00610 typedef THash<TStrPr, TStr> TStrPrStrH; 00611 typedef THash<TStrPr, TStrV> TStrPrStrVH; 00612 typedef THash<TStrTr, TInt> TStrTrIntH; 00613 typedef THash<TStrIntPr, TInt> TStrIntPrIntH; 00614 typedef THash<TStrV, TInt> TStrVH; 00615 typedef THash<TStrV, TInt> TStrVIntH; 00616 typedef THash<TStrV, TIntV> TStrVIntVH; 00617 typedef THash<TStrV, TStr> TStrVStrH; 00618 typedef THash<TStrV, TStrV> TStrVStrVH; 00619 00621 // Hash-Pointer 00622 template <class TKey, class TDat> 00623 class PHash{ 00624 private: 00625 TCRef CRef; 00626 public: 00627 THash<TKey, TDat> H; 00628 public: 00629 PHash<TKey, TDat>(): H(){} 00630 static TPt<PHash<TKey, TDat> > New(){ 00631 return new PHash<TKey, TDat>();} 00632 PHash<TKey, TDat>(const int& MxVals, const int& Vals): H(MxVals, Vals){} 00633 static TPt<PHash<TKey, TDat> > New(const int& MxVals, const int& Vals){ 00634 return new PHash<TKey, TDat>(MxVals, Vals);} 00635 PHash<TKey, TDat>(const THash<TKey, TDat>& _V): H(_V){} 00636 static TPt<PHash<TKey, TDat> > New(const THash<TKey, TDat>& H){ 00637 return new PHash<TKey, TDat>(H);} 00638 explicit PHash<TKey, TDat>(TSIn& SIn): H(SIn){} 00639 static TPt<PHash<TKey, TDat> > Load(TSIn& SIn){return new PHash<TKey, TDat>(SIn);} 00640 void Save(TSOut& SOut) const {H.Save(SOut);} 00641 00642 PHash<TKey, TDat>& operator=(const PHash<TKey, TDat>& Vec){ 00643 if (this!=&Vec){H=Vec.H;} return *this;} 00644 bool operator==(const PHash<TKey, TDat>& Vec) const {return H==Vec.H;} 00645 bool operator<(const PHash<TKey, TDat>& Vec) const {return H<Vec.H;} 00646 00647 friend class TPt<PHash<TKey, TDat> >; 00648 }; 00649 00651 // Big-String-Pool (holds up to 2 giga strings, storage overhead is 8(4) bytes per string) 00652 //J: have to put it here since it uses TVec (can't be in dt.h) 00653 ClassTP(TBigStrPool, PBigStrPool)//{ 00654 private: 00655 TSize MxBfL, BfL; 00656 uint GrowBy; 00657 char *Bf; 00658 TVec<TSize> IdOffV; // string ID to offset 00659 private: 00660 void Resize(TSize _MxBfL); 00661 public: 00662 TBigStrPool(TSize MxBfLen = 0, uint _GrowBy = 16*1024*1024); 00663 TBigStrPool(TSIn& SIn, bool LoadCompact = true); 00664 TBigStrPool(const TBigStrPool& Pool) : MxBfL(Pool.MxBfL), BfL(Pool.BfL), GrowBy(Pool.GrowBy) { 00665 Bf = (char *) malloc(Pool.MxBfL); IAssert(Bf); memcpy(Bf, Pool.Bf, Pool.BfL); } 00666 ~TBigStrPool() { if (Bf) free(Bf); else IAssert(MxBfL == 0); MxBfL = 0; BfL = 0; } 00667 00668 static PBigStrPool New(TSize _MxBfLen = 0, uint _GrowBy = 16*1024*1024) { return PBigStrPool(new TBigStrPool(_MxBfLen, _GrowBy)); } 00669 static PBigStrPool New(TSIn& SIn) { return new TBigStrPool(SIn); } 00670 static PBigStrPool New(const TStr& fileName) { PSIn SIn = TFIn::New(fileName); return new TBigStrPool(*SIn); } 00671 static PBigStrPool Load(TSIn& SIn, bool LoadCompacted = true) { return PBigStrPool(new TBigStrPool(SIn, LoadCompacted)); } 00672 void Save(TSOut& SOut) const; 00673 void Save(const TStr& fileName) { TFOut FOut(fileName); Save(FOut); } 00674 00675 int GetStrs() const { return IdOffV.Len(); } 00676 TSize Len() const { return BfL; } 00677 TSize Size() const { return MxBfL; } 00678 bool Empty() const { return ! Len(); } 00679 char* operator () () const { return Bf; } 00680 TBigStrPool& operator = (const TBigStrPool& Pool); 00681 00682 int AddStr(const char *Str, uint Len); 00683 int AddStr(const char *Str) { return AddStr(Str, uint(strlen(Str)) + 1); } 00684 int AddStr(const TStr& Str) { return AddStr(Str.CStr(), Str.Len() + 1); } 00685 00686 TStr GetStr(const int& StrId) const { Assert(StrId < GetStrs()); 00687 if (StrId == 0) return TStr::GetNullStr(); else return TStr(Bf + (TSize)IdOffV[StrId]); } 00688 const char *GetCStr(const int& StrId) const { Assert(StrId < GetStrs()); 00689 if (StrId == 0) return TStr::GetNullStr().CStr(); else return (Bf + (TSize)IdOffV[StrId]); } 00690 00691 TStr GetStrFromOffset(const TSize& Offset) const { Assert(Offset < BfL); 00692 if (Offset == 0) return TStr::GetNullStr(); else return TStr(Bf + Offset); } 00693 const char *GetCStrFromOffset(const TSize& Offset) const { Assert(Offset < BfL); 00694 if (Offset == 0) return TStr::GetNullStr().CStr(); else return Bf + Offset; } 00695 00696 void Clr(bool DoDel = false) { BfL = 0; if (DoDel && Bf) { free(Bf); Bf = 0; MxBfL = 0; } } 00697 int Cmp(const int& StrId, const char *Str) const { Assert(StrId < GetStrs()); 00698 if (StrId != 0) return strcmp(Bf + (TSize)IdOffV[StrId], Str); else return strcmp("", Str); } 00699 00700 static int GetPrimHashCd(const char *CStr); 00701 static int GetSecHashCd(const char *CStr); 00702 int GetPrimHashCd(const int& StrId) { Assert(StrId < GetStrs()); 00703 if (StrId != 0) return GetPrimHashCd(Bf + (TSize)IdOffV[StrId]); else return GetPrimHashCd(""); } 00704 int GetSecHashCd(const int& StrId) { Assert(StrId < GetStrs()); 00705 if (StrId != 0) return GetSecHashCd(Bf + (TSize)IdOffV[StrId]); else return GetSecHashCd(""); } 00706 }; 00707 00709 // String-Hash-Table 00710 template <class TDat, class TStringPool = TStrPool, class THashFunc = TDefaultHashFunc<TStr> > 00711 class TStrHash{ 00712 private: 00713 //typedef typename PStringPool::TObj TStringPool; 00714 typedef TPt<TStringPool> PStringPool; 00715 typedef THashKeyDat<TInt, TDat> THKeyDat; 00716 typedef TPair<TInt, TDat> TKeyDatP; 00717 typedef TVec<THKeyDat> THKeyDatV; 00718 TIntV PortV; 00719 THKeyDatV KeyDatV; 00720 TBool AutoSizeP; 00721 TInt FFreeKeyId, FreeKeys; 00722 PStringPool Pool; 00723 private: 00724 uint GetNextPrime(const uint& Val) const; 00725 void Resize(); 00726 const THKeyDat& GetHashKeyDat(const int& KeyId) const { 00727 const THKeyDat& KeyDat = KeyDatV[KeyId]; Assert(KeyDat.HashCd != -1); return KeyDat; } 00728 THKeyDat& GetHashKeyDat(const int& KeyId) { 00729 THKeyDat& KeyDat = KeyDatV[KeyId]; Assert(KeyDat.HashCd != -1); return KeyDat; } 00730 public: 00731 TStrHash(): PortV(), KeyDatV(), AutoSizeP(true), FFreeKeyId(-1), FreeKeys(0), Pool() { } 00732 TStrHash(const PStringPool& StrPool): PortV(), KeyDatV(), AutoSizeP(true), FFreeKeyId(-1), FreeKeys(0), Pool(StrPool) { } 00733 TStrHash(const int& Ports, const bool& _AutoSizeP = false, const PStringPool& StrPool = PStringPool()) : 00734 PortV(Ports), KeyDatV(Ports, 0), AutoSizeP(_AutoSizeP), FFreeKeyId(-1), FreeKeys(0), Pool(StrPool) { PortV.PutAll(-1); } 00735 TStrHash(const TStrHash& Hash): PortV(Hash.PortV), KeyDatV(Hash.KeyDatV), AutoSizeP(Hash.AutoSizeP), 00736 FFreeKeyId(Hash.FFreeKeyId), FreeKeys(Hash.FreeKeys), Pool() { 00737 if (! Hash.Pool.Empty()) { Pool=PStringPool(new TStringPool(*Hash.Pool)); } } 00738 TStrHash(TSIn& SIn, bool PoolToo = true): PortV(SIn), KeyDatV(SIn), AutoSizeP(SIn), FFreeKeyId(SIn), FreeKeys(SIn){ SIn.LoadCs(); if (PoolToo) Pool = PStringPool(SIn); } 00739 00740 void Load(TSIn& SIn, bool PoolToo = true) { PortV.Load(SIn); KeyDatV.Load(SIn); AutoSizeP.Load(SIn); FFreeKeyId.Load(SIn); 00741 FreeKeys.Load(SIn); SIn.LoadCs(); if (PoolToo) Pool = PStringPool(SIn); } 00742 void Save(TSOut& SOut, bool PoolToo = true) const { PortV.Save(SOut); KeyDatV.Save(SOut); 00743 AutoSizeP.Save(SOut); FFreeKeyId.Save(SOut); FreeKeys.Save(SOut); SOut.SaveCs(); if (PoolToo) Pool.Save(SOut); } 00744 00745 void SetPool(const PStringPool& StrPool) { IAssert(Pool.Empty() || Pool->Empty()); Pool = StrPool; } 00746 PStringPool GetPool() const { return Pool; } 00747 00748 TStrHash& operator = (const TStrHash& Hash); 00749 00750 bool Empty() const {return ! Len(); } 00751 int Len() const { return KeyDatV.Len() - FreeKeys; } 00752 int Reserved() const { return KeyDatV.Reserved(); } 00753 int GetPorts() const { return PortV.Len(); } 00754 bool IsAutoSize() const { return AutoSizeP; } 00755 int GetMxKeyIds() const { return KeyDatV.Len(); } 00756 bool IsKeyIdEqKeyN() const {return ! FreeKeys; } 00757 00758 int AddKey(const char *Key); 00759 int AddKey(const TStr& Key) { return AddKey(Key.CStr()); } 00760 int AddKey(const TChA& Key) { return AddKey(Key.CStr()); } 00761 int AddDat(const char *Key, const TDat& Dat) { const int KeyId = AddKey(Key); KeyDatV[KeyId].Dat = Dat; return KeyId; } 00762 int AddDat(const TStr& Key, const TDat& Dat) { const int KeyId = AddKey(Key.CStr()); KeyDatV[KeyId].Dat = Dat; return KeyId; } 00763 int AddDat(const TChA& Key, const TDat& Dat) { const int KeyId = AddKey(Key.CStr()); KeyDatV[KeyId].Dat = Dat; return KeyId; } 00764 TDat& AddDat(const char *Key) { return KeyDatV[AddKey(Key)].Dat; } 00765 TDat& AddDat(const TStr& Key) { return KeyDatV[AddKey(Key.CStr())].Dat; } 00766 TDat& AddDat(const TChA& Key) { return KeyDatV[AddKey(Key.CStr())].Dat; } 00767 TDat& AddDatId(const char *Key) { const int KeyId = AddKey(Key); return KeyDatV[KeyId].Dat = KeyId; } 00768 TDat& AddDatId(const TStr& Key) { const int KeyId = AddKey(Key.CStr()); return KeyDatV[KeyId].Dat = KeyId; } 00769 TDat& AddDatId(const TChA& Key) { const int KeyId = AddKey(Key.CStr()); return KeyDatV[KeyId].Dat = KeyId; } 00770 00771 const TDat& operator[](const int& KeyId) const {return GetHashKeyDat(KeyId).Dat;} 00772 TDat& operator[](const int& KeyId){return GetHashKeyDat(KeyId).Dat;} 00773 const TDat& operator () (const char *Key) const { return GetDat(Key);} 00774 //TDat& operator ()(const char *Key){return AddDat(Key);} // add if not found 00775 00776 const TDat& GetDat(const char *Key) const { return KeyDatV[GetKeyId(Key)].Dat; } 00777 const TDat& GetDat(const TStr& Key) const { return GetDat(Key.CStr()); } 00778 TDat& GetDat(const char *Key) { return KeyDatV[GetKeyId(Key)].Dat; } 00779 const TDat& GetDat(const TStr& Key) { return GetDat(Key.CStr()); } 00780 const TDat& GetDat(const TChA& Key) { return GetDat(Key.CStr()); } 00781 TDat& GetDatId(const int& KeyId) { return KeyDatV[KeyId].Dat; } 00782 const TDat& GetDatId(const int& KeyId) const { return KeyDatV[KeyId].Dat; } 00783 void GetKeyDat(const int& KeyId, int& KeyO, TDat& Dat) const { const THKeyDat& KeyDat = GetHashKeyDat(KeyId); KeyO = KeyDat.Key; Dat = KeyDat.Dat; } 00784 void GetKeyDat(const int& KeyId, const char*& Key, TDat& Dat) const { const THKeyDat& KeyDat = GetHashKeyDat(KeyId); Key = KeyFromOfs(KeyDat.Key); Dat = KeyDat.Dat; } 00785 void GetKeyDat(const int& KeyId, TStr& Key, TDat& Dat) const { const THKeyDat& KeyDat = GetHashKeyDat(KeyId); Key = KeyFromOfs(KeyDat.Key); Dat = KeyDat.Dat;} 00786 void GetKeyDat(const int& KeyId, TChA& Key, TDat& Dat) const { const THKeyDat& KeyDat = GetHashKeyDat(KeyId); Key = KeyFromOfs(KeyDat.Key); Dat = KeyDat.Dat;} 00787 00788 int GetKeyId(const char *Key) const; 00789 int GetKeyId(const TStr& Key) const { return GetKeyId(Key.CStr()); } 00790 const char *GetKey(const int& KeyId) const { return Pool->GetCStr(GetHashKeyDat(KeyId).Key); } 00791 int GetKeyOfs(const int& KeyId) const { return GetHashKeyDat(KeyId).Key; } // pool string id 00792 const char *KeyFromOfs(const int& KeyO) const { return Pool->GetCStr(KeyO); } 00793 00794 bool IsKey(const char *Key) const { return GetKeyId(Key) != -1; } 00795 bool IsKey(const TStr& Key) const { return GetKeyId(Key.CStr()) != -1; } 00796 bool IsKey(const TChA& Key) const { return GetKeyId(Key.CStr()) != -1; } 00797 bool IsKey(const char *Key, int& KeyId) const { KeyId = GetKeyId(Key); return KeyId != -1; } 00798 bool IsKeyGetDat(const char *Key, TDat& Dat) const { const int KeyId = GetKeyId(Key); if (KeyId != -1) { Dat = KeyDatV[KeyId].Dat; return true; } else return false; } 00799 bool IsKeyGetDat(const TStr& Key, TDat& Dat) const { const int KeyId = GetKeyId(Key.CStr()); if (KeyId != -1) { Dat = KeyDatV[KeyId].Dat; return true; } else return false; } 00800 bool IsKeyGetDat(const TChA& Key, TDat& Dat) const { const int KeyId = GetKeyId(Key.CStr()); if (KeyId != -1) { Dat = KeyDatV[KeyId].Dat; return true; } else return false; } 00801 bool IsKeyId(const int& KeyId) const { return 0 <= KeyId && KeyId < KeyDatV.Len() && KeyDatV[KeyId].HashCd != -1; } 00802 00803 int FFirstKeyId() const {return 0-1;} 00804 bool FNextKeyId(int& KeyId) const; 00805 00806 void GetKeyV(TVec<TStr>& KeyV) const; 00807 void GetStrIdV(TIntV& StrIdV) const; 00808 void GetDatV(TVec<TDat>& DatV) const; 00809 void GetKeyDatPrV(TVec<TPair<TStr, TDat> >& KeyDatPrV) const; 00810 void GetDatKeyPrV(TVec<TPair<TDat, TStr> >& DatKeyPrV) const; 00811 00812 void Pack(){KeyDatV.Pack();} 00813 }; 00814 00815 template <class TDat, class TStringPool, class THashFunc> 00816 uint TStrHash<TDat, TStringPool, THashFunc>::GetNextPrime(const uint& Val) const { 00817 uint *f = (uint *) TIntH::HashPrimeT, *m, *l = (uint *) TIntH::HashPrimeT + (int) TIntH::HashPrimes; 00818 int h, len = (int)TIntH::HashPrimes; 00819 while (len > 0) { 00820 h = len >> 1; m = f + h; 00821 if (*m < Val) { f = m; f++; len = len - h - 1; } 00822 else len = h; 00823 } 00824 return f == l ? *(l - 1) : *f; 00825 } 00826 00827 template <class TDat, class TStringPool, class THashFunc> 00828 void TStrHash<TDat, TStringPool, THashFunc>::Resize() { 00829 // resize & initialize port vector 00830 if (PortV.Empty()) { PortV.Gen(17); PortV.PutAll(-1); } 00831 else 00832 if (AutoSizeP && KeyDatV.Len() > 3 * PortV.Len()) { 00833 const int NxPrime = GetNextPrime(KeyDatV.Len()); 00834 //printf("%s resize PortV: %d -> %d, Len: %d\n", GetTypeNm(*this).CStr(), PortV.Len(), NxPrime, Len()); 00835 PortV.Gen(NxPrime); PortV.PutAll(-1); } 00836 else 00837 return; 00838 // rehash keys 00839 const int NPorts = PortV.Len(); 00840 for (int i = 0; i < KeyDatV.Len(); i++) { 00841 THKeyDat& KeyDat = KeyDatV[i]; 00842 if (KeyDat.HashCd != -1) { 00843 const int Port = abs(THashFunc::GetPrimHashCd(Pool->GetCStr(KeyDat.Key)) % NPorts); 00844 KeyDat.Next = PortV[Port]; 00845 PortV[Port] = i; 00846 } 00847 } 00848 } 00849 00850 template <class TDat, class TStringPool, class THashFunc> 00851 TStrHash<TDat, TStringPool, THashFunc>& TStrHash<TDat, TStringPool, THashFunc>:: operator = (const TStrHash& Hash) { 00852 if (this != &Hash) { 00853 PortV = Hash.PortV; 00854 KeyDatV = Hash.KeyDatV; 00855 AutoSizeP = Hash.AutoSizeP; 00856 FFreeKeyId = Hash.FFreeKeyId; 00857 FreeKeys = Hash.FreeKeys; 00858 if (! Hash.Pool.Empty()) Pool = PStringPool(new TStringPool(*Hash.Pool)); 00859 else Pool = NULL; 00860 } 00861 return *this; 00862 } 00863 00864 template <class TDat, class TStringPool, class THashFunc> 00865 int TStrHash<TDat, TStringPool, THashFunc>::AddKey(const char *Key) { 00866 if (Pool.Empty()) Pool = TStringPool::New(); 00867 if ((AutoSizeP && KeyDatV.Len() > PortV.Len()) || PortV.Empty()) Resize(); 00868 const int PortN = abs(THashFunc::GetPrimHashCd(Key) % PortV.Len()); 00869 const int HashCd = abs(THashFunc::GetSecHashCd(Key)); 00870 int PrevKeyId = -1; 00871 int KeyId = PortV[PortN]; 00872 while (KeyId != -1 && ! (KeyDatV[KeyId].HashCd == HashCd && Pool->Cmp(KeyDatV[KeyId].Key, Key) == 0)) { 00873 PrevKeyId = KeyId; KeyId = KeyDatV[KeyId].Next; } 00874 if (KeyId == -1) { 00875 const int StrId = Pool->AddStr(Key); 00876 if (FFreeKeyId == -1) { 00877 KeyId = KeyDatV.Add(THKeyDat(-1, HashCd, StrId)); 00878 } else { 00879 KeyId = FFreeKeyId; 00880 FFreeKeyId = KeyDatV[FFreeKeyId].Next; 00881 FreeKeys--; 00882 KeyDatV[KeyId] = THKeyDat(-1, HashCd, StrId); 00883 } 00884 if (PrevKeyId == -1) PortV[PortN] = KeyId; 00885 else KeyDatV[PrevKeyId].Next = KeyId; 00886 } 00887 return KeyId; 00888 } 00889 00890 template <class TDat, class TStringPool, class THashFunc> 00891 int TStrHash<TDat, TStringPool, THashFunc>::GetKeyId(const char *Key) const { 00892 if (PortV.Empty()) return -1; 00893 const int PortN = abs(THashFunc::GetPrimHashCd(Key) % PortV.Len()); 00894 const int Hc = abs(THashFunc::GetSecHashCd(Key)); 00895 int KeyId = PortV[PortN]; 00896 while (KeyId != -1 && ! (KeyDatV[KeyId].HashCd == Hc && Pool->Cmp(KeyDatV[KeyId].Key, Key) == 0)) 00897 KeyId = KeyDatV[KeyId].Next; 00898 return KeyId; 00899 } 00900 00901 template <class TDat, class TStringPool, class THashFunc> 00902 bool TStrHash<TDat, TStringPool, THashFunc>::FNextKeyId(int& KeyId) const { 00903 do KeyId++; while (KeyId < KeyDatV.Len() && KeyDatV[KeyId].HashCd == -1); 00904 return KeyId < KeyDatV.Len(); 00905 } 00906 00907 template <class TDat, class TStringPool, class THashFunc> 00908 void TStrHash<TDat, TStringPool, THashFunc>::GetKeyV(TVec<TStr>& KeyV) const { 00909 KeyV.Gen(Len(), 0); 00910 int KeyId = FFirstKeyId(); 00911 while (FNextKeyId(KeyId)) 00912 KeyV.Add(GetKey(KeyId)); 00913 } 00914 00915 template <class TDat, class TStringPool, class THashFunc> 00916 void TStrHash<TDat, TStringPool, THashFunc>::GetStrIdV(TIntV& StrIdV) const { 00917 StrIdV.Gen(Len(), 0); 00918 int KeyId = FFirstKeyId(); 00919 while (FNextKeyId(KeyId)) 00920 StrIdV.Add(GetKeyOfs(KeyId)); 00921 } 00922 00923 template <class TDat, class TStringPool, class THashFunc> 00924 void TStrHash<TDat, TStringPool, THashFunc>::GetDatV(TVec<TDat>& DatV) const { 00925 DatV.Gen(Len(), 0); 00926 int KeyId = FFirstKeyId(); 00927 while (FNextKeyId(KeyId)) 00928 DatV.Add(GetHashKeyDat(KeyId).Dat); 00929 } 00930 00931 template <class TDat, class TStringPool, class THashFunc> 00932 void TStrHash<TDat, TStringPool, THashFunc>::GetKeyDatPrV(TVec<TPair<TStr, TDat> >& KeyDatPrV) const { 00933 KeyDatPrV.Gen(Len(), 0); 00934 TStr Str; TDat Dat; 00935 int KeyId = FFirstKeyId(); 00936 while (FNextKeyId(KeyId)){ 00937 GetKeyDat(KeyId, Str, Dat); 00938 KeyDatPrV.Add(TPair<TStr, TDat>(Str, Dat)); 00939 } 00940 } 00941 00942 template <class TDat, class TStringPool, class THashFunc> 00943 void TStrHash<TDat, TStringPool, THashFunc>::GetDatKeyPrV(TVec<TPair<TDat, TStr> >& DatKeyPrV) const { 00944 DatKeyPrV.Gen(Len(), 0); 00945 TStr Str; TDat Dat; 00946 int KeyId = FFirstKeyId(); 00947 while (FNextKeyId(KeyId)){ 00948 GetKeyDat(KeyId, Str, Dat); 00949 DatKeyPrV.Add(TPair<TDat, TStr>(Dat, Str)); 00950 } 00951 } 00952 00954 // Common-String-Hash-Types 00955 typedef TStrHash<TInt> TStrSH; 00956 typedef TStrHash<TInt> TStrIntSH; 00957 typedef TStrHash<TIntV> TStrToIntVSH; 00958 00960 // Cache 00961 template <class TKey, class TDat, class THashFunc = TDefaultHashFunc<TKey> > 00962 class TCache{ 00963 private: 00964 typedef TLst<TKey> TKeyL; typedef TLstNd<TKey>* TKeyLN; 00965 typedef TPair<TKeyLN, TDat> TKeyLNDatPr; 00966 int64 MxMemUsed; 00967 int64 CurMemUsed; 00968 THash<TKey, TKeyLNDatPr, THashFunc> KeyDatH; 00969 TKeyL TimeKeyL; 00970 void* RefToBs; 00971 void Purge(const int64& MemToPurge); 00972 public: 00973 TCache(){} 00974 TCache(const TCache&); 00975 TCache(const int64& _MxMemUsed, const int& Ports, void* _RefToBs): 00976 MxMemUsed(_MxMemUsed), CurMemUsed(0), 00977 KeyDatH(Ports), TimeKeyL(), RefToBs(_RefToBs){} 00978 00979 TCache& operator=(const TCache&); 00980 int64 GetMemUsed() const; 00981 bool RefreshMemUsed(); 00982 00983 void Put(const TKey& Key, const TDat& Dat); 00984 bool Get(const TKey& Key, TDat& Dat); 00985 void Del(const TKey& Key, const bool& DoEventCall=true); 00986 void Flush(); 00987 void FlushAndClr(); 00988 void* FFirstKeyDat(); 00989 bool FNextKeyDat(void*& KeyDatP, TKey& Key, TDat& Dat); 00990 00991 void PutRefToBs(void* _RefToBs){RefToBs=_RefToBs;} 00992 void* GetRefToBs(){return RefToBs;} 00993 }; 00994 00995 template <class TKey, class TDat, class THashFunc> 00996 void TCache<TKey, TDat, THashFunc>::Purge(const int64& MemToPurge){ 00997 const int64 StartMemUsed = CurMemUsed; 00998 while (!TimeKeyL.Empty()&&(StartMemUsed-CurMemUsed<MemToPurge)){ 00999 TKey Key=TimeKeyL.Last()->GetVal(); 01000 Del(Key); 01001 } 01002 } 01003 01004 template <class TKey, class TDat, class THashFunc> 01005 int64 TCache<TKey, TDat, THashFunc>::GetMemUsed() const { 01006 int64 MemUsed=0; 01007 int KeyId=KeyDatH.FFirstKeyId(); 01008 while (KeyDatH.FNextKeyId(KeyId)){ 01009 const TKey& Key=KeyDatH.GetKey(KeyId); 01010 const TKeyLNDatPr& KeyLNDatPr=KeyDatH[KeyId]; 01011 TDat Dat=KeyLNDatPr.Val2; 01012 MemUsed+=int64(Key.GetMemUsed()+Dat->GetMemUsed()); 01013 } 01014 return MemUsed; 01015 } 01016 01017 template <class TKey, class TDat, class THashFunc> 01018 bool TCache<TKey, TDat, THashFunc>::RefreshMemUsed(){ 01019 CurMemUsed=GetMemUsed(); 01020 if (CurMemUsed>MxMemUsed){ 01021 Purge(CurMemUsed-MxMemUsed); 01022 return true; 01023 } 01024 return false; 01025 } 01026 01027 template <class TKey, class TDat, class THashFunc> 01028 void TCache<TKey, TDat, THashFunc>::Put(const TKey& Key, const TDat& Dat){ 01029 int KeyId=KeyDatH.GetKeyId(Key); 01030 if (KeyId==-1){ 01031 int64 KeyDatMem=int64(Key.GetMemUsed()+Dat->GetMemUsed()); 01032 if (CurMemUsed+KeyDatMem>MxMemUsed){Purge(KeyDatMem);} 01033 CurMemUsed+=KeyDatMem; 01034 TKeyLN KeyLN=TimeKeyL.AddFront(Key); 01035 TKeyLNDatPr KeyLNDatPr(KeyLN, Dat); 01036 KeyDatH.AddDat(Key, KeyLNDatPr); 01037 } else { 01038 TKeyLNDatPr& KeyLNDatPr=KeyDatH[KeyId]; 01039 TKeyLN KeyLN=KeyLNDatPr.Val1; 01040 KeyLNDatPr.Val2=Dat; 01041 TimeKeyL.PutFront(KeyLN); 01042 } 01043 } 01044 01045 template <class TKey, class TDat, class THashFunc> 01046 bool TCache<TKey, TDat, THashFunc>::Get(const TKey& Key, TDat& Dat){ 01047 int KeyId=KeyDatH.GetKeyId(Key); 01048 if (KeyId==-1){ 01049 return false; 01050 } else { 01051 Dat=KeyDatH[KeyId].Val2; 01052 return true; 01053 } 01054 } 01055 01056 template <class TKey, class TDat, class THashFunc> 01057 void TCache<TKey, TDat, THashFunc>::Del(const TKey& Key, const bool& DoEventCall){ 01058 int KeyId=KeyDatH.GetKeyId(Key); 01059 if (KeyId!=-1){ 01060 TKeyLNDatPr& KeyLNDatPr=KeyDatH[KeyId]; 01061 TKeyLN KeyLN=KeyLNDatPr.Val1; 01062 TDat& Dat=KeyLNDatPr.Val2; 01063 if (DoEventCall){ 01064 Dat->OnDelFromCache(Key, RefToBs);} 01065 CurMemUsed-=int64(Key.GetMemUsed()+Dat->GetMemUsed()); 01066 Dat=NULL; 01067 TimeKeyL.Del(KeyLN); 01068 KeyDatH.DelKeyId(KeyId); 01069 } 01070 } 01071 01072 template <class TKey, class TDat, class THashFunc> 01073 void TCache<TKey, TDat, THashFunc>::Flush(){ 01074 printf("To flush: %d\n", KeyDatH.Len()); 01075 int KeyId=KeyDatH.FFirstKeyId(); int Done = 0; 01076 while (KeyDatH.FNextKeyId(KeyId)){ 01077 if (Done%10000==0){printf("%d\r", Done);} 01078 const TKey& Key=KeyDatH.GetKey(KeyId); 01079 TKeyLNDatPr& KeyLNDatPr=KeyDatH[KeyId]; 01080 TDat Dat=KeyLNDatPr.Val2; 01081 Dat->OnDelFromCache(Key, RefToBs); 01082 Done++; 01083 } 01084 printf("Done %d\n", KeyDatH.Len()); 01085 } 01086 01087 template <class TKey, class TDat, class THashFunc> 01088 void TCache<TKey, TDat, THashFunc>::FlushAndClr(){ 01089 Flush(); 01090 CurMemUsed=0; 01091 KeyDatH.Clr(); 01092 TimeKeyL.Clr(); 01093 } 01094 01095 template <class TKey, class TDat, class THashFunc> 01096 void* TCache<TKey, TDat, THashFunc>::FFirstKeyDat(){ 01097 return TimeKeyL.First(); 01098 } 01099 01100 template <class TKey, class TDat, class THashFunc> 01101 bool TCache<TKey, TDat, THashFunc>::FNextKeyDat(void*& KeyDatP, TKey& Key, TDat& Dat){ 01102 if (KeyDatP==NULL){ 01103 return false; 01104 } else { 01105 Key=TKeyLN(KeyDatP)->GetVal(); Dat=KeyDatH.GetDat(Key).Val2; 01106 KeyDatP=TKeyLN(KeyDatP)->Next(); return true; 01107 } 01108 } 01109 01111 // String-Hash-Functions 01112 01113 // Old-String-Hash-Function 01114 class TStrHashF_OldGLib { 01115 public: 01116 inline static int GetPrimHashCd(const char *p) { 01117 const int MulBy = 16; // even older version used MulBy=2 01118 int HashCd = 0; 01119 while (*p) { HashCd = (MulBy * HashCd) + *p++; HashCd &= 0x0FFFFFFF; } 01120 return HashCd; } 01121 inline static int GetSecHashCd(const char *p) { 01122 const int MulBy = 16; // even older version used MulBy=2 01123 int HashCd = 0; 01124 while (*p) { HashCd = (MulBy * HashCd) ^ *p++; HashCd &= 0x0FFFFFFF; } 01125 return HashCd; } 01126 inline static int GetPrimHashCd(const TStr& s) { return GetPrimHashCd(s.CStr()); } 01127 inline static int GetSecHashCd(const TStr& s) { return GetSecHashCd(s.CStr()); } 01128 }; 01129 01130 // Md5-Hash-Function 01131 class TStrHashF_Md5 { 01132 public: 01133 static int GetPrimHashCd(const char *p); 01134 static int GetSecHashCd(const char *p); 01135 static int GetPrimHashCd(const TStr& s); 01136 static int GetSecHashCd(const TStr& s); 01137 }; 01138 01139 // DJB-Hash-Function 01140 class TStrHashF_DJB { 01141 private: 01142 inline static unsigned int DJBHash(const char* Str, const ::TSize& Len) { 01143 unsigned int hash = 5381; 01144 for(unsigned int i = 0; i < Len; Str++, i++) { 01145 hash = ((hash << 5) + hash) + (*Str); } 01146 return hash; 01147 } 01148 public: 01149 inline static int GetPrimHashCd(const char *p) { 01150 const char *r = p; while (*r) { r++; } 01151 return (int) DJBHash((const char *) p, r - p) & 0x7fffffff; } 01152 inline static int GetSecHashCd(const char *p) { 01153 const char *r = p; while (*r) { r++; } 01154 return (int) DJBHash((const char *) p, r - p) & 0x7fffffff; } 01155 inline static int GetPrimHashCd(const TStr& s) { return GetPrimHashCd(s.CStr()); } 01156 inline static int GetSecHashCd(const TStr& s) { return GetSecHashCd(s.CStr()); } 01157 };