SNAP Library, User Reference  2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
fds.h
Go to the documentation of this file.
00001 
00002 // Forward
00003 template <class TKey, class TFDat, class TVDat>
00004 class TFHash;
00005 
00006 typedef enum {fhbtUndef, fhbtKey, fhbtVDat} TFHashBlobType;
00007 
00009 // File-Hash-Table-Key-Data
00010 template <class TKey, class TFDat, class TVDat>
00011 class TFHashKey{
00012 private:
00013   TCRef CRef;
00014   bool Modified;
00015 public:
00016   typedef TPt<TFHashKey<TKey, TFDat, TVDat> > PFHashKey;
00017   typedef TFHash<TKey, TFDat, TVDat> THash;
00018   TBlobPt Next;
00019   TKey Key;
00020   TFDat FDat;
00021   TBlobPt VDatBPt;
00022 public:
00023   TFHashKey():
00024     Modified(false), Next(), Key(), FDat(), VDatBPt(){}
00025   TFHashKey(const TBlobPt& _Next,
00026    const TKey& _Key, const TFDat& _FDat, const TBlobPt& _VDatBPt=TBlobPt()):
00027     Modified(false), Next(_Next), Key(_Key), FDat(_FDat), VDatBPt(_VDatBPt){}
00028   ~TFHashKey(){}
00029   TFHashKey(TSIn& SIn):
00030     Modified(false), Next(SIn), Key(SIn), FDat(SIn), VDatBPt(SIn){}
00031   static PFHashKey Load(TSIn& SIn){return new TFHashKey(SIn);}
00032   void Save(TSOut& SOut){
00033     Next.Save(SOut); Key.Save(SOut); FDat.Save(SOut); VDatBPt.Save(SOut);}
00034 
00035   TFHashKey& operator=(const TFHashKey& FHashKey){
00036     if (this!=&FHashKey){
00037       Modified=true; Next=FHashKey.Next;
00038       Key=FHashKey.Key; FDat=FHashKey.FDat; VDatBPt=FHashKey.VDatBPt;}
00039     return *this;}
00040   int GetMemUsed() const {
00041     return sizeof(THash*)+Next.GetMemUsed()+
00042      Key.GetMemUsed()+FDat.GetMemUsed()+VDatBPt.GetMemUsed();}
00043 
00044   void PutModified(const bool& _Modified){Modified=_Modified;}
00045 
00046   void OnDelFromCache(const TBlobPt& BlobPt, void* RefToBs);
00047 
00048   friend class TPt<TFHashKey<TKey, TFDat, TVDat> >;
00049 };
00050 
00051 template <class TKey, class TFDat, class TVDat>
00052 void TFHashKey<TKey, TFDat, TVDat>::OnDelFromCache(
00053  const TBlobPt& BlobPt, void* RefToBs){
00054   if (Modified){
00055     // prepare hash table object
00056     THash* FHash=(THash*)RefToBs;
00057     // save the key
00058     TMOut MOut; TInt(int(fhbtKey)).Save(MOut); Save(MOut);
00059     TBlobPt NewBlobPt=FHash->GetHashBBs()->PutBlob(BlobPt, MOut.GetSIn());
00060     // blob-pointer for key should not change
00061     IAssert(NewBlobPt==BlobPt);
00062   }
00063 }
00064 
00066 // File-Hash-Table
00067 
00068 template <class TKey, class TFDat, class TVDat>
00069 class TFHash{
00070 private:
00071   TCRef CRef;
00072 private:
00073   typedef TPt<TFHash<TKey, TFDat, TVDat> > PFHash;
00074   typedef TFHashKey<TKey, TFDat, TVDat> THashKey;
00075   typedef TPt<THashKey> PHashKey;
00076   TFAccess Access;
00077   PBlobBs HashBBs;
00078   TBlobPtV PortV;
00079   TInt Keys;
00080   TCache<TBlobPt, PHashKey> FHashKeyCache;
00081 private:
00082   void* GetVoidThis() const {return (void*)this;}
00083   PBlobBs GetHashBBs(){return HashBBs;}
00084   PHashKey GetFHashKey(const TBlobPt& KeyId){
00085     PHashKey FHashKey;
00086     if (!FHashKeyCache.Get(KeyId, FHashKey)){ // if the key is in cache
00087       // read the key from blob-base
00088       PSIn SIn=HashBBs->GetBlob(KeyId);
00089       TFHashBlobType Type=TFHashBlobType(int(TInt(*SIn))); IAssert(Type==fhbtKey);
00090       FHashKey=PHashKey(new THashKey(*SIn));
00091     }
00092     FHashKeyCache.Put(KeyId, FHashKey); // refresh/put key in cache
00093     return FHashKey;
00094   }
00095   void GetKeyInfo(const TKey& Key,
00096    int& PortN, TBlobPt& PrevKeyId, TBlobPt& KeyId, PHashKey& FHashKey);
00097   void GetKeyInfo(const TKey& Key, TBlobPt& KeyId, PHashKey& FHashKey){
00098     int PortN=-1; TBlobPt PrevKeyId;
00099     GetKeyInfo(Key, PortN, PrevKeyId, KeyId, FHashKey);}
00100 private:
00101   TBlobPt AddKey(const TKey& Key,
00102    const bool& ChangeFDat, const TFDat& FDat,
00103    const bool& ChangeVDatBPt, const TBlobPt& VDatBPt);
00104   TBlobPt AddDat(
00105    const TKey& Key,
00106    const bool& ChangeFDat, const TFDat& FDat,
00107    const bool& ChangeVDat, const TVDat& VDat);
00108 public:
00109   TFHash(const TStr& HashFNm, const TFAccess& _Access,
00110    const int& Ports, const int& MxMemUsed);
00111   ~TFHash();
00112   TFHash(TSIn&){Fail;}
00113   static PFHash Load(TSIn&){Fail; return NULL;}
00114   void Save(TSOut&){Fail;}
00115 
00116   TFHash& operator=(const TFHash&){Fail; return *this;}
00117   int GetMemUsed(){
00118     return PortV.GetMemUsed()+(int)FHashKeyCache.GetMemUsed();} //TODO:64bit
00119   void CacheFlushAndClr(){FHashKeyCache.FlushAndClr();}
00120 
00121   bool Empty() const {return Keys==0;}
00122   int Len() const {return Keys;}
00123 
00124   TBlobPt AddFDat(const TKey& Key, const TFDat& FDat){
00125     return AddKey(Key, true, FDat, false, TBlobPt());}
00126   TBlobPt AddVDat(const TKey& Key, const TVDat& VDat){
00127     return AddDat(Key, false, TFDat(), true, VDat);}
00128   TBlobPt AddFVDat(const TKey& Key, const TFDat& FDat, const TVDat& VDat){
00129     return AddDat(Key, true, FDat, true, VDat);}
00130 
00131   void DelKey(const TKey& Key);
00132   void DelKeyId(const TBlobPt& KeyId){
00133     TKey Key; GetKey(KeyId, Key); DelKey(Key);}
00134 
00135   void GetKey(const TBlobPt& KeyId, TKey& Key){
00136     PHashKey FHashKey=GetFHashKey(KeyId); Key=FHashKey->Key;}
00137   TBlobPt GetKeyId(const TKey& Key){
00138     TBlobPt KeyId; PHashKey FHashKey; GetKeyInfo(Key, KeyId, FHashKey);
00139     return KeyId;}
00140   bool IsKey(const TKey& Key){
00141     return !GetKeyId(Key).Empty();}
00142   bool IsKey(const TKey& Key, TBlobPt& KeyId){
00143     KeyId=GetKeyId(Key); return !KeyId.Empty();}
00144 
00145   TBlobPt GetFDat(const TKey& Key, TFDat& FDat);
00146   TBlobPt GetVDat(const TKey& Key, TVDat& VDat);
00147   TBlobPt GetFVDat(const TKey& Key, TFDat& FDat, TVDat& VDat);
00148   void GetKeyFDat(const TBlobPt& KeyId, TKey& Key, TFDat& FDat);
00149   void GetKeyFVDat(const TBlobPt& KeyId, TKey& Key, TFDat& FDat, TVDat& VDat);
00150 
00151   TBlobPt FFirstKeyId();
00152   bool FNextKeyId(TBlobPt& TrvBlobPt, TBlobPt& KeyId);
00153 
00154   friend class TFHashKey<TKey, TFDat, TVDat>;
00155   friend class TPt<TFHash<TKey, TFDat, TVDat> >;
00156 };
00157 
00158 
00159 template <class TKey, class TFDat, class TVDat>
00160 void TFHash<TKey, TFDat, TVDat>::GetKeyInfo(
00161  const TKey& Key,
00162  int& PortN, TBlobPt& PrevKeyId, TBlobPt& KeyId, PHashKey& FHashKey){
00163   // prepare key data
00164   PortN=abs(Key.GetPrimHashCd())%PortV.Len();
00165   PrevKeyId.Clr();
00166   KeyId=PortV[PortN];
00167 
00168   // test if the key exists
00169   if (!KeyId.Empty()){
00170     FHashKey=GetFHashKey(KeyId);
00171     while ((!KeyId.Empty())&&(FHashKey->Key!=Key)){
00172       PrevKeyId=KeyId;
00173       KeyId=FHashKey->Next;
00174       if (!KeyId.Empty()){FHashKey=GetFHashKey(KeyId);}
00175     }
00176   }
00177 }
00178 
00179 template <class TKey, class TFDat, class TVDat>
00180 TFHash<TKey, TFDat, TVDat>::TFHash(
00181  const TStr& HashFNm, const TFAccess& _Access,
00182  const int& Ports, const int& MxMemUsed):
00183   Access(_Access), HashBBs(), PortV(), Keys(0),
00184   FHashKeyCache(MxMemUsed, 100003, GetVoidThis()){
00185   if (Access==faCreate){
00186     IAssert(Ports>0);
00187     // create blob-base
00188     HashBBs=PBlobBs(new TGBlobBs(HashFNm, faCreate));
00189     // save initial no. of keys and port-vector
00190     PortV.Gen(Ports);
00191     TMOut HdSOut; Keys.Save(HdSOut); PortV.Save(HdSOut);
00192     HashBBs->PutBlob(HdSOut.GetSIn());
00193   } else {
00194     IAssert((Access==faUpdate)||(Access==faRdOnly));
00195     IAssert(Ports==-1);
00196     // open blob-base
00197     HashBBs=PBlobBs(new TGBlobBs(HashFNm, Access));
00198     // load initial no. of keys and port-vector
00199     TBlobPt HdBPt=HashBBs->GetFirstBlobPt();
00200     PSIn HdSIn=HashBBs->GetBlob(HdBPt);
00201     Keys=TInt(*HdSIn);
00202     PortV=TBlobPtV(*HdSIn);
00203   }
00204 }
00205 
00206 template <class TKey, class TFDat, class TVDat>
00207 TFHash<TKey, TFDat, TVDat>::~TFHash(){
00208   if ((Access==faCreate)||(Access==faUpdate)){
00209     // flush hash-key cache
00210     FHashKeyCache.Flush();
00211     // save port-vector
00212     TBlobPt HdBPt=HashBBs->GetFirstBlobPt();
00213     TMOut HdSOut; Keys.Save(HdSOut); PortV.Save(HdSOut);
00214     HashBBs->PutBlob(HdBPt, HdSOut.GetSIn());
00215   }
00216 }
00217 
00218 template <class TKey, class TFDat, class TVDat>
00219 TBlobPt TFHash<TKey, TFDat, TVDat>::AddKey(
00220  const TKey& Key,
00221  const bool& ChangeFDat, const TFDat& FDat,
00222  const bool& ChangeVDatBPt, const TBlobPt& VDatBPt){
00223   // prepare key info
00224   int PortN=-1; TBlobPt PrevKeyId; TBlobPt KeyId; PHashKey FHashKey;
00225   GetKeyInfo(Key, PortN, PrevKeyId, KeyId, FHashKey);
00226 
00227   if (KeyId.Empty()){
00228     // generate key
00229     FHashKey=PHashKey(new THashKey(TBlobPt(), Key, FDat, VDatBPt));
00230     // save key to blob-base
00231     TMOut FHashKeyMOut;
00232     TInt(int(fhbtKey)).Save(FHashKeyMOut); FHashKey->Save(FHashKeyMOut);
00233     TBlobPt FHashKeyBPt=HashBBs->PutBlob(FHashKeyMOut.GetSIn());
00234     // save key to key-cache
00235     FHashKeyCache.Put(FHashKeyBPt, FHashKey);
00236     FHashKey->PutModified(false);
00237     // connect key to the structure
00238     KeyId=FHashKeyBPt;
00239     Keys++;
00240     if (PrevKeyId.Empty()){
00241       PortV[PortN]=KeyId;
00242     } else {
00243       PHashKey PrevFHashKey=GetFHashKey(PrevKeyId);
00244       PrevFHashKey->Next=KeyId;
00245       PrevFHashKey->PutModified(true);
00246     }
00247   } else {
00248     // update the data
00249     if (ChangeFDat){FHashKey->FDat=FDat;}
00250     if (ChangeVDatBPt){FHashKey->VDatBPt=VDatBPt;}
00251     if (ChangeFDat||ChangeVDatBPt){
00252       FHashKey->PutModified(true);}
00253   }
00254   return KeyId;
00255 }
00256 
00257 template <class TKey, class TFDat, class TVDat>
00258 TBlobPt TFHash<TKey, TFDat, TVDat>::AddDat(
00259  const TKey& Key,
00260  const bool& ChangeFDat, const TFDat& FDat,
00261  const bool& ChangeVDat, const TVDat& VDat){
00262   // prepare key info
00263   TBlobPt KeyId; PHashKey FHashKey;
00264   GetKeyInfo(Key, KeyId, FHashKey);
00265 
00266   // prepare new variable-data blob-pointer
00267   TBlobPt VDatBPt;
00268   if (ChangeVDat){
00269     // save variable-data
00270     TMOut VDatMOut;
00271     TInt(int(fhbtVDat)).Save(VDatMOut); VDat.Save(VDatMOut);
00272     if (KeyId.Empty()){
00273       VDatBPt=HashBBs->PutBlob(VDatMOut.GetSIn());
00274     } else {
00275       VDatBPt=HashBBs->PutBlob(FHashKey->VDatBPt, VDatMOut.GetSIn());
00276     }
00277   }
00278 
00279   // save the data
00280   KeyId=AddKey(Key, ChangeFDat, FDat, ChangeVDat, VDatBPt);
00281   return KeyId;
00282 }
00283 
00284 template <class TKey, class TFDat, class TVDat>
00285 void TFHash<TKey, TFDat, TVDat>::DelKey(const TKey& Key){
00286   // prepare key info
00287   int PortN=-1; TBlobPt PrevKeyId; TBlobPt KeyId; PHashKey FHashKey;
00288   GetKeyInfo(Key, PortN, PrevKeyId, KeyId, FHashKey);
00289 
00290   // disconnect key
00291   IAssert(!KeyId.Empty());
00292   if (PrevKeyId.Empty()){
00293     PortV[PortN]=FHashKey->Next;
00294   } else {
00295     PHashKey PrevFHashKey=GetFHashKey(PrevKeyId);
00296     PrevFHashKey->Next=FHashKey->Next;
00297     PrevFHashKey->PutModified(true);
00298   }
00299   // delete variable data
00300   if (!FHashKey->VDatBPt.Empty()){
00301     HashBBs->DelBlob(FHashKey->VDatBPt);}
00302   // delete key/fixed data
00303   HashBBs->DelBlob(KeyId);
00304   FHashKeyCache.Del(KeyId, false);
00305 }
00306 
00307 template <class TKey, class TFDat, class TVDat>
00308 TBlobPt TFHash<TKey, TFDat, TVDat>::GetFDat(
00309  const TKey& Key, TFDat& FDat){
00310   // prepare key info
00311   TBlobPt KeyId; PHashKey FHashKey;
00312   GetKeyInfo(Key, KeyId, FHashKey);
00313   // get fixed data
00314   FDat=FHashKey->FDat;
00315   return KeyId;
00316 }
00317 
00318 template <class TKey, class TFDat, class TVDat>
00319 TBlobPt TFHash<TKey, TFDat, TVDat>::GetVDat(const TKey& Key, TVDat& VDat){
00320   // prepare key info
00321   TBlobPt KeyId; PHashKey FHashKey;
00322   GetKeyInfo(Key, KeyId, FHashKey);
00323   // get variable data
00324   PSIn SIn=HashBBs->GetBlob(FHashKey->VDatBPt);
00325   TFHashBlobType Type=TFHashBlobType(int(TInt(*SIn))); IAssert(Type==fhbtVDat);
00326   VDat=TVDat(*SIn);
00327   return KeyId;
00328 }
00329 
00330 template <class TKey, class TFDat, class TVDat>
00331 TBlobPt TFHash<TKey, TFDat, TVDat>::GetFVDat(
00332  const TKey& Key, TFDat& FDat, TVDat& VDat){
00333   // prepare key info
00334   TBlobPt KeyId; PHashKey FHashKey;
00335   GetKeyInfo(Key, KeyId, FHashKey);
00336   // get fixed data
00337   FDat=FHashKey->FDat;
00338   // get variable data
00339   PSIn SIn=HashBBs->GetBlob(FHashKey->VDatBPt);
00340   TFHashBlobType Type=TFHashBlobType(int(TInt(*SIn))); IAssert(Type==fhbtVDat);
00341   VDat=TVDat(*SIn);
00342   return KeyId;
00343 }
00344 
00345 template <class TKey, class TFDat, class TVDat>
00346 void TFHash<TKey, TFDat, TVDat>::GetKeyFDat(
00347  const TBlobPt& KeyId, TKey& Key, TFDat& FDat){
00348   // prepare key info
00349   PHashKey FHashKey=GetFHashKey(KeyId);
00350   // get key
00351   Key=FHashKey->Key;
00352   // get fixed data
00353   FDat=FHashKey->FDat;
00354 }
00355 
00356 template <class TKey, class TFDat, class TVDat>
00357 void TFHash<TKey, TFDat, TVDat>::GetKeyFVDat(
00358  const TBlobPt& KeyId, TKey& Key, TFDat& FDat, TVDat& VDat){
00359   // prepare key info
00360   PHashKey FHashKey=GetFHashKey(KeyId);
00361   // get key
00362   Key=FHashKey->Key;
00363   // get fixed data
00364   FDat=FHashKey->FDat;
00365   // get variable data
00366   PSIn SIn=HashBBs->GetBlob(FHashKey->VDatBPt);
00367   TFHashBlobType Type=TFHashBlobType(int(TInt(*SIn))); IAssert(Type==fhbtVDat);
00368   VDat=TVDat(*SIn);
00369 }
00370 
00371 template <class TKey, class TFDat, class TVDat>
00372 TBlobPt TFHash<TKey, TFDat, TVDat>::FFirstKeyId(){
00373   return HashBBs->FFirstBlobPt();
00374 }
00375 
00376 template <class TKey, class TFDat, class TVDat>
00377 bool TFHash<TKey, TFDat, TVDat>::FNextKeyId(
00378  TBlobPt& TrvBlobPt, TBlobPt& KeyId){
00379   PSIn SIn;
00380   while (HashBBs->FNextBlobPt(TrvBlobPt, KeyId, SIn)){
00381     TFHashBlobType Type=TFHashBlobType(int(TInt(*SIn)));
00382     if (Type==fhbtKey){return true;}
00383   }
00384   return false;
00385 }
00386