SNAP Library , Developer Reference  2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
hash.h
Go to the documentation of this file.
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 };