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