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