SNAP Library , Developer Reference
2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 00002 // Blob-Pointer 00003 const int TBlobPt::Flags=24; 00004 00005 void TBlobPt::PutFlag(const int& FlagN, const bool& Val){ 00006 EAssert((0<=FlagN)&&(FlagN<Flags)); 00007 switch (FlagN/8){ 00008 case 0: FSet1.SetBit(7-FlagN%8, Val); break; 00009 case 1: FSet2.SetBit(7-FlagN%8, Val); break; 00010 case 2: FSet3.SetBit(7-FlagN%8, Val); break; 00011 default: Fail; 00012 } 00013 } 00014 00015 bool TBlobPt::IsFlag(const int& FlagN) const { 00016 EAssert((0<=FlagN)&&(FlagN<Flags)); 00017 switch (FlagN/8){ 00018 case 0: return FSet1.GetBit(7-FlagN%8); 00019 case 1: return FSet2.GetBit(7-FlagN%8); 00020 case 2: return FSet3.GetBit(7-FlagN%8); 00021 default: Fail; return false; 00022 } 00023 } 00024 00025 void TBlobPt::PutFSet(const int& FSetN, const TB8Set& FSet){ 00026 switch (FSetN){ 00027 case 1: FSet1=FSet; break; 00028 case 2: FSet2=FSet; break; 00029 case 3: FSet3=FSet; break; 00030 default: Fail; 00031 } 00032 } 00033 00034 TB8Set TBlobPt::GetFSet(const int& FSetN){ 00035 switch (FSetN){ 00036 case 1: return FSet1; 00037 case 2: return FSet2; 00038 case 3: return FSet3; 00039 default: Fail; return TB8Set(); 00040 } 00041 } 00042 00043 TStr TBlobPt::GetStr() const { 00044 TChA ChA; 00045 ChA+='['; 00046 if (Empty()){ 00047 ChA+="Null"; 00048 } else { 00049 ChA+=TUInt::GetStr(uint(Seg)); ChA+=':'; ChA+=TUInt::GetStr(Addr); 00050 for (int FlagN=0; FlagN<Flags; FlagN++){ 00051 if (IsFlag(FlagN)){ 00052 ChA+='{'; ChA+=TInt::GetStr(FlagN); ChA+='}';} 00053 } 00054 } 00055 ChA+=']'; 00056 return ChA; 00057 } 00058 00060 // Blob-Base 00061 const int TBlobBs::MnBlobBfL=16; 00062 const int TBlobBs::MxBlobFLen=1000000000; 00063 00064 void TBlobBs::PutVersionStr(const PFRnd& FBlobBs){ 00065 FBlobBs->PutStr(GetVersionStr()); 00066 } 00067 00068 void TBlobBs::AssertVersionStr(const PFRnd& FBlobBs){ 00069 TStr CorrVersionStr=GetVersionStr(); 00070 bool IsOk=false; 00071 TStr TestVersionStr=FBlobBs->GetStr(CorrVersionStr.Len(), IsOk); 00072 EAssert(IsOk && (CorrVersionStr==TestVersionStr)); 00073 } 00074 00075 TStr TBlobBs::GetBlobBsStateStr(const TBlobBsState& BlobBsState){ 00076 TStr StateStr; 00077 switch (BlobBsState){ 00078 case bbsOpened: StateStr="Opened"; break; 00079 case bbsClosed: StateStr="Closed"; break; 00080 default: Fail; return TStr(); 00081 } 00082 EAssert(StateStr.Len()==GetStateStrLen()); 00083 return StateStr; 00084 } 00085 00086 void TBlobBs::PutBlobBsStateStr(const PFRnd& FBlobBs, const TBlobBsState& State){ 00087 FBlobBs->PutStr(GetBlobBsStateStr(State)); 00088 } 00089 00090 void TBlobBs::AssertBlobBsStateStr( 00091 const PFRnd& FBlobBs, const TBlobBsState& State){ 00092 TStr CorrStateStr=GetBlobBsStateStr(State); 00093 bool IsOk; 00094 TStr TestStateStr=FBlobBs->GetStr(GetStateStrLen(), IsOk); 00095 if (!(IsOk && (CorrStateStr==TestStateStr))) { 00096 TExcept::ThrowFull("Error in AssertBlobBsStateStr!", TStr(__FILE__)+" line "+TInt::GetStr(__LINE__)); 00097 } 00098 } 00099 00100 const TStr TBlobBs::MxSegLenVNm="MxSegLen"; 00101 00102 void TBlobBs::PutMxSegLen(const PFRnd& FBlobBs, const int& MxSegLen){ 00103 FBlobBs->PutStr(MxSegLenVNm); 00104 FBlobBs->PutInt(MxSegLen); 00105 } 00106 00107 int TBlobBs::GetMxSegLen(const PFRnd& FBlobBs){ 00108 EAssert(FBlobBs->GetStr(MxSegLenVNm.Len())==MxSegLenVNm); 00109 return FBlobBs->GetInt(); 00110 } 00111 00112 const TStr TBlobBs::BlockLenVNm="BlockLenV"; 00113 00114 void TBlobBs::GenBlockLenV(TIntV& BlockLenV){ 00115 BlockLenV.Clr(); 00116 for (int P2Exp=0; P2Exp<TB4Def::MxP2Exp; P2Exp++){ 00117 BlockLenV.Add(TInt(TB4Def::GetP2(P2Exp)));} 00118 EAssert(int(BlockLenV.Last())<2000000000); 00119 00120 {for (int Len=10; Len<100; Len+=10){BlockLenV.Add(Len);}} 00121 {for (int Len=100; Len<10000; Len+=100){BlockLenV.Add(Len);}} 00122 {for (int Len=10000; Len<100000; Len+=1000){BlockLenV.Add(Len);}} 00123 {for (int Len=100000; Len<1000000; Len+=25000){BlockLenV.Add(Len);}} 00124 {for (int Len=1000000; Len<10000000; Len+=1000000){BlockLenV.Add(Len);}} 00125 {for (int Len=10000000; Len<100000000; Len+=10000000){BlockLenV.Add(Len);}} 00126 00127 BlockLenV.Sort(); 00128 } 00129 00130 void TBlobBs::PutBlockLenV(const PFRnd& FBlobBs, const TIntV& BlockLenV){ 00131 FBlobBs->PutStr(BlockLenVNm); 00132 FBlobBs->PutInt(BlockLenV.Len()); 00133 for (int BlockLenN=0; BlockLenN<BlockLenV.Len(); BlockLenN++){ 00134 FBlobBs->PutInt(BlockLenV[BlockLenN]);} 00135 FBlobBs->PutInt(-1); 00136 } 00137 00138 void TBlobBs::GetBlockLenV(const PFRnd& FBlobBs, TIntV& BlockLenV){ 00139 EAssert(FBlobBs->GetStr(BlockLenVNm.Len())==BlockLenVNm); 00140 BlockLenV.Gen(FBlobBs->GetInt()); 00141 for (int BlockLenN=0; BlockLenN<BlockLenV.Len(); BlockLenN++){ 00142 BlockLenV[BlockLenN]=FBlobBs->GetInt();} 00143 EAssert(FBlobBs->GetInt()==-1); 00144 } 00145 00146 const TStr TBlobBs::FFreeBlobPtVNm="FFreeBlobPtV"; 00147 00148 void TBlobBs::GenFFreeBlobPtV(const TIntV& BlockLenV, TBlobPtV& FFreeBlobPtV){ 00149 FFreeBlobPtV.Gen(BlockLenV.Len()+1); 00150 } 00151 00152 void TBlobBs::PutFFreeBlobPtV(const PFRnd& FBlobBs, const TBlobPtV& FFreeBlobPtV){ 00153 FBlobBs->PutStr(FFreeBlobPtVNm); 00154 FBlobBs->PutInt(FFreeBlobPtV.Len()); 00155 for (int BlockLenN=0; BlockLenN<FFreeBlobPtV.Len(); BlockLenN++){ 00156 FFreeBlobPtV[BlockLenN].Save(FBlobBs);} 00157 FBlobBs->PutInt(-1); 00158 } 00159 00160 void TBlobBs::GetFFreeBlobPtV(const PFRnd& FBlobBs, TBlobPtV& FFreeBlobPtV){ 00161 EAssert(FBlobBs->GetStr(FFreeBlobPtVNm.Len())==FFreeBlobPtVNm); 00162 FFreeBlobPtV.Gen(FBlobBs->GetInt()); 00163 for (int FFreeBlobPtN=0; FFreeBlobPtN<FFreeBlobPtV.Len(); FFreeBlobPtN++){ 00164 FFreeBlobPtV[FFreeBlobPtN]=TBlobPt::Load(FBlobBs);} 00165 EAssert(FBlobBs->GetInt()==-1); 00166 } 00167 00168 void TBlobBs::GetAllocInfo( 00169 const int& BfL, const TIntV& BlockLenV, int& MxBfL, int& FFreeBlobPtN){ 00170 int BlockLenN=0; 00171 while ((BlockLenN<BlockLenV.Len())&&(BfL>BlockLenV[BlockLenN])){ 00172 BlockLenN++;} 00173 EAssert(BlockLenN<BlockLenV.Len()); 00174 MxBfL=BlockLenV[BlockLenN]; FFreeBlobPtN=BlockLenN; 00175 } 00176 00177 void TBlobBs::PutBlobTag(const PFRnd& FBlobBs, const TBlobTag& BlobTag){ 00178 switch (BlobTag){ 00179 case btBegin: FBlobBs->PutUInt(GetBeginBlobTag()); break; 00180 case btEnd: FBlobBs->PutUInt(GetEndBlobTag()); break; 00181 default: Fail; 00182 } 00183 } 00184 00185 void TBlobBs::AssertBlobTag(const PFRnd& FBlobBs, const TBlobTag& BlobTag){ 00186 switch (BlobTag){ 00187 case btBegin: EAssert(FBlobBs->GetUInt()==GetBeginBlobTag()); break; 00188 case btEnd: EAssert(FBlobBs->GetUInt()==GetEndBlobTag()); break; 00189 default: TExcept::Throw("Error asserting BlobTag"); 00190 } 00191 } 00192 00193 void TBlobBs::PutBlobState(const PFRnd& FBlobBs, const TBlobState& State){ 00194 FBlobBs->PutCh(char(State)); 00195 } 00196 00197 TBlobState TBlobBs::GetBlobState(const PFRnd& FBlobBs){ 00198 return TBlobState(int(FBlobBs->GetCh())); 00199 } 00200 00201 void TBlobBs::AssertBlobState(const PFRnd& FBlobBs, const TBlobState& State){ 00202 EAssert(TBlobState(FBlobBs->GetCh())==State); 00203 } 00204 00205 void TBlobBs::AssertBfCsEqFlCs(const TCs& BfCs, const TCs& FCs){ 00206 if (BfCs!=FCs){ 00207 printf("[%d:%d]\n", BfCs.Get(), FCs.Get());} 00208 //EAssert(BfCs==FCs); 00209 } 00210 00212 // General-Blob-Base 00213 TStr TGBlobBs::GetNrBlobBsFNm(const TStr& BlobBsFNm){ 00214 TStr NrBlobBsFNm=BlobBsFNm; 00215 if (NrBlobBsFNm.GetFExt().Empty()){ 00216 NrBlobBsFNm=NrBlobBsFNm+".gbb";} 00217 return NrBlobBsFNm; 00218 } 00219 00220 TGBlobBs::TGBlobBs( 00221 const TStr& BlobBsFNm, const TFAccess& _Access, const int& _MxSegLen): 00222 TBlobBs(), FBlobBs(), Access(_Access), MxSegLen(_MxSegLen), 00223 BlockLenV(), FFreeBlobPtV(TB4Def::B4Bits), FirstBlobPt(){ 00224 if (MxSegLen==-1){MxSegLen=MxBlobFLen;} 00225 TStr NrBlobBsFNm=GetNrBlobBsFNm(BlobBsFNm); 00226 switch (Access){ 00227 case faCreate: 00228 FBlobBs=TFRnd::New(NrBlobBsFNm, faCreate, true); break; 00229 case faUpdate: 00230 case faRdOnly: 00231 case faRestore: 00232 FBlobBs=TFRnd::New(NrBlobBsFNm, faUpdate, true); break; 00233 default: Fail; 00234 } 00235 if (FBlobBs->Empty()){ 00236 FBlobBs->SetFPos(0); 00237 PutVersionStr(FBlobBs); 00238 PutBlobBsStateStr(FBlobBs, bbsOpened); 00239 PutMxSegLen(FBlobBs, MxSegLen); 00240 GenBlockLenV(BlockLenV); 00241 PutBlockLenV(FBlobBs, BlockLenV); 00242 GenFFreeBlobPtV(BlockLenV, FFreeBlobPtV); 00243 PutFFreeBlobPtV(FBlobBs, FFreeBlobPtV); 00244 } else { 00245 FBlobBs->SetFPos(0); 00246 AssertVersionStr(FBlobBs); 00247 int FPos=FBlobBs->GetFPos(); 00248 if (Access!=faRestore){ 00249 AssertBlobBsStateStr(FBlobBs, bbsClosed);} 00250 if (Access!=faRdOnly){ 00251 FBlobBs->SetFPos(FPos); 00252 PutBlobBsStateStr(FBlobBs, bbsOpened); 00253 } 00254 MxSegLen=GetMxSegLen(FBlobBs); 00255 GetBlockLenV(FBlobBs, BlockLenV); 00256 GetFFreeBlobPtV(FBlobBs, FFreeBlobPtV); 00257 } 00258 FirstBlobPt=TBlobPt(FBlobBs->GetFPos()); 00259 FBlobBs->Flush(); 00260 } 00261 00262 TGBlobBs::~TGBlobBs(){ 00263 if (Access!=faRdOnly){ 00264 FBlobBs->SetFPos(0); 00265 PutVersionStr(FBlobBs); 00266 PutBlobBsStateStr(FBlobBs, bbsClosed); 00267 PutMxSegLen(FBlobBs, MxSegLen); 00268 PutBlockLenV(FBlobBs, BlockLenV); 00269 PutFFreeBlobPtV(FBlobBs, FFreeBlobPtV); 00270 } 00271 FBlobBs->Flush(); 00272 FBlobBs=NULL; 00273 } 00274 00275 TBlobPt TGBlobBs::PutBlob(const PSIn& SIn){ 00276 EAssert((Access==faCreate)||(Access==faUpdate)||(Access==faRestore)); 00277 int BfL=SIn->Len(); 00278 int MxBfL; int FFreeBlobPtN; 00279 GetAllocInfo(BfL, BlockLenV, MxBfL, FFreeBlobPtN); 00280 TBlobPt BlobPt; TCs Cs; 00281 if (FFreeBlobPtV[FFreeBlobPtN].Empty()){ 00282 int FLen=FBlobBs->GetFLen(); 00283 if (FLen<=MxSegLen){ 00284 EAssert(FLen<=MxBlobFLen); 00285 BlobPt=TBlobPt(FLen); 00286 FBlobBs->SetFPos(BlobPt.GetAddr()); 00287 PutBlobTag(FBlobBs, btBegin); 00288 FBlobBs->PutInt(MxBfL); 00289 PutBlobState(FBlobBs, bsActive); 00290 FBlobBs->PutInt(BfL); 00291 FBlobBs->PutSIn(SIn, Cs); 00292 FBlobBs->PutCh(TCh::NullCh, MxBfL-BfL); 00293 FBlobBs->PutCs(Cs); 00294 PutBlobTag(FBlobBs, btEnd); 00295 } 00296 } else { 00297 BlobPt=FFreeBlobPtV[FFreeBlobPtN]; 00298 FBlobBs->SetFPos(BlobPt.GetAddr()); 00299 AssertBlobTag(FBlobBs, btBegin); 00300 int MxBfL=FBlobBs->GetInt(); 00301 int FPos=FBlobBs->GetFPos(); 00302 AssertBlobState(FBlobBs, bsFree); 00303 FFreeBlobPtV[FFreeBlobPtN]=TBlobPt::LoadAddr(FBlobBs); 00304 FBlobBs->SetFPos(FPos); 00305 PutBlobState(FBlobBs, bsActive); 00306 FBlobBs->PutInt(BfL); 00307 FBlobBs->PutSIn(SIn, Cs); 00308 FBlobBs->PutCh(TCh::NullCh, MxBfL-BfL); 00309 FBlobBs->PutCs(Cs); 00310 AssertBlobTag(FBlobBs, btEnd); 00311 } 00312 FBlobBs->Flush(); 00313 return BlobPt; 00314 } 00315 00316 TBlobPt TGBlobBs::PutBlob(const TBlobPt& BlobPt, const PSIn& SIn){ 00317 EAssert((Access==faCreate)||(Access==faUpdate)||(Access==faRestore)); 00318 int BfL=SIn->Len(); 00319 00320 FBlobBs->SetFPos(BlobPt.GetAddr()); 00321 AssertBlobTag(FBlobBs, btBegin); 00322 int MxBfL=FBlobBs->GetInt(); 00323 AssertBlobState(FBlobBs, bsActive); 00324 if (BfL>MxBfL){ 00325 DelBlob(BlobPt); 00326 return PutBlob(SIn); 00327 } else { 00328 TCs Cs; 00329 FBlobBs->PutInt(BfL); 00330 FBlobBs->PutSIn(SIn, Cs); 00331 FBlobBs->PutCh(TCh::NullCh, MxBfL-BfL); 00332 FBlobBs->PutCs(Cs); 00333 PutBlobTag(FBlobBs, btEnd); 00334 FBlobBs->Flush(); 00335 return BlobPt; 00336 } 00337 } 00338 00339 PSIn TGBlobBs::GetBlob(const TBlobPt& BlobPt){ 00340 FBlobBs->SetFPos(BlobPt.GetAddr()); 00341 AssertBlobTag(FBlobBs, btBegin); 00342 int MxBfL=FBlobBs->GetInt(); 00343 AssertBlobState(FBlobBs, bsActive); 00344 int BfL=FBlobBs->GetInt(); 00345 TCs BfCs; PSIn SIn=FBlobBs->GetSIn(BfL, BfCs); 00346 FBlobBs->MoveFPos(MxBfL-BfL); 00347 TCs FCs=FBlobBs->GetCs(); 00348 AssertBlobTag(FBlobBs, btEnd); 00349 AssertBfCsEqFlCs(BfCs, FCs); 00350 return SIn; 00351 } 00352 00353 void TGBlobBs::DelBlob(const TBlobPt& BlobPt){ 00354 EAssert((Access==faCreate)||(Access==faUpdate)||(Access==faRestore)); 00355 FBlobBs->SetFPos(BlobPt.GetAddr()); 00356 AssertBlobTag(FBlobBs, btBegin); 00357 int MxBfL=FBlobBs->GetInt(); 00358 int FPos=FBlobBs->GetFPos(); 00359 AssertBlobState(FBlobBs, bsActive); 00360 /*int BfL=*/FBlobBs->GetInt(); 00361 FBlobBs->SetFPos(FPos); 00362 PutBlobState(FBlobBs, bsFree); 00363 int _MxBfL; int FFreeBlobPtN; 00364 GetAllocInfo(MxBfL, BlockLenV, _MxBfL, FFreeBlobPtN); 00365 EAssert(MxBfL==_MxBfL); 00366 FFreeBlobPtV[FFreeBlobPtN].SaveAddr(FBlobBs); 00367 FFreeBlobPtV[FFreeBlobPtN]=BlobPt; 00368 FBlobBs->PutCh(TCh::NullCh, MxBfL+sizeof(TCs)); 00369 AssertBlobTag(FBlobBs, btEnd); 00370 FBlobBs->Flush(); 00371 } 00372 00373 TBlobPt TGBlobBs::FFirstBlobPt(){ 00374 return FirstBlobPt; 00375 } 00376 00377 bool TGBlobBs::FNextBlobPt(TBlobPt& TrvBlobPt, TBlobPt& BlobPt, PSIn& BlobSIn){ 00378 forever { 00379 uint TrvBlobAddr=TrvBlobPt.GetAddr(); 00380 if (TrvBlobAddr>=uint(FBlobBs->GetFLen())){ 00381 TrvBlobPt.Clr(); BlobPt.Clr(); BlobSIn=NULL; 00382 return false; 00383 } else { 00384 FBlobBs->SetFPos(TrvBlobAddr); 00385 AssertBlobTag(FBlobBs, btBegin); 00386 int MxBfL=FBlobBs->GetInt(); 00387 TBlobState BlobState=GetBlobState(FBlobBs); 00388 switch (BlobState){ 00389 case bsActive:{ 00390 int BfL=FBlobBs->GetInt(); 00391 TCs BfCs; BlobSIn=FBlobBs->GetSIn(BfL, BfCs); 00392 FBlobBs->MoveFPos(MxBfL-BfL); 00393 TCs FCs=FBlobBs->GetCs(); 00394 AssertBlobTag(FBlobBs, btEnd); 00395 AssertBfCsEqFlCs(BfCs, FCs); 00396 BlobPt=TrvBlobPt; 00397 TrvBlobPt=TBlobPt(FBlobBs->GetFPos()); 00398 return true;} 00399 case bsFree: 00400 FBlobBs->MoveFPos(sizeof(uint)+MxBfL+sizeof(TCs)); 00401 AssertBlobTag(FBlobBs, btEnd); 00402 TrvBlobPt=TBlobPt(FBlobBs->GetFPos()); 00403 break; 00404 default: Fail; return false; 00405 } 00406 } 00407 } 00408 } 00409 00410 bool TGBlobBs::Exists(const TStr& BlobBsFNm){ 00411 TStr NrBlobBsFNm=GetNrBlobBsFNm(BlobBsFNm); 00412 return TFile::Exists(NrBlobBsFNm); 00413 } 00414 00416 // Multiple-File-Blob-Base 00417 void TMBlobBs::GetNrFPathFMid( 00418 const TStr& BlobBsFNm, TStr& NrFPath, TStr& NrFMid){ 00419 NrFPath=TStr::GetNrFPath(BlobBsFNm.GetFPath()); 00420 NrFMid=TStr::GetNrFMid(BlobBsFNm.GetFMid()); 00421 } 00422 00423 TStr TMBlobBs::GetMainFNm( 00424 const TStr& NrFPath, const TStr& NrFMid){ 00425 return NrFPath+NrFMid+".mbb"; 00426 } 00427 00428 TStr TMBlobBs::GetSegFNm( 00429 const TStr& NrFPath, const TStr& NrFMid, const int& SegN){ 00430 return NrFPath+NrFMid+".mbb"+""+TStr::GetNrNumFExt(SegN); 00431 } 00432 00433 void TMBlobBs::LoadMain(int& Segs){ 00434 PSIn SIn=TFIn::New(GetMainFNm(NrFPath, NrFMid)); 00435 TILx Lx(SIn, TFSet()|oloFrcEoln|oloSigNum|oloCsSens); 00436 EAssert(Lx.GetVarStr("Version")==GetVersionStr()); 00437 MxSegLen=Lx.GetVarInt("MxSegLen"); 00438 Segs=Lx.GetVarInt("Segments"); 00439 } 00440 00441 void TMBlobBs::SaveMain() const { 00442 PSOut SOut=TFOut::New(GetMainFNm(NrFPath, NrFMid)); 00443 TOLx Lx(SOut, TFSet()|oloFrcEoln|oloSigNum|oloCsSens); 00444 Lx.PutVarStr("Version", GetVersionStr()); 00445 Lx.PutVarInt("MxSegLen", MxSegLen); 00446 Lx.PutVarInt("Segments", SegV.Len()); 00447 } 00448 00449 TMBlobBs::TMBlobBs( 00450 const TStr& BlobBsFNm, const TFAccess& _Access, const int& _MxSegLen): 00451 TBlobBs(), Access(_Access), MxSegLen(_MxSegLen), 00452 NrFPath(), NrFMid(), SegV(), CurSegN(0){ 00453 if (MxSegLen==-1){MxSegLen=MxBlobFLen;} 00454 GetNrFPathFMid(BlobBsFNm, NrFPath, NrFMid); 00455 switch (Access){ 00456 case faCreate:{ 00457 TFile::DelWc(BlobBsFNm+".*"); 00458 TStr SegFNm=GetSegFNm(NrFPath, NrFMid, 0); 00459 PBlobBs Seg=TGBlobBs::New(SegFNm, faCreate, MxSegLen); 00460 SegV.Add(Seg); 00461 SaveMain(); break;} 00462 case faUpdate: 00463 case faRdOnly:{ 00464 int Segs; LoadMain(Segs); 00465 for (int SegN=0; SegN<Segs; SegN++){ 00466 TStr SegFNm=GetSegFNm(NrFPath, NrFMid, SegN); 00467 SegV.Add(TGBlobBs::New(SegFNm, Access, MxSegLen)); 00468 } 00469 break;} 00470 case faRestore:{ 00471 // assume no segments 00472 int Segs=-1; 00473 // if main-file exists 00474 if (TFile::Exists(GetMainFNm(NrFPath, NrFMid))){ 00475 // load main file 00476 int _Segs; LoadMain(_Segs); 00477 // load segment-files which exist 00478 Segs=0; 00479 forever { 00480 // get segment file-name 00481 TStr SegFNm=GetSegFNm(NrFPath, NrFMid, Segs); 00482 // if segment-file exists then add segment else break check-loop 00483 if (TFile::Exists(SegFNm)){ 00484 SegV.Add(TGBlobBs::New(SegFNm, Access, MxSegLen)); 00485 Segs++; 00486 } else { 00487 break; 00488 } 00489 } 00490 } 00491 // if no segments exist then create blob-base from scratch 00492 if (Segs==-1){ 00493 TStr SegFNm=GetSegFNm(NrFPath, NrFMid, 0); 00494 PBlobBs Seg=TGBlobBs::New(SegFNm, faCreate, MxSegLen); 00495 SegV.Add(Seg); 00496 SaveMain(); 00497 } 00498 break;} 00499 default: Fail; 00500 } 00501 } 00502 00503 TMBlobBs::~TMBlobBs(){ 00504 if (Access!=faRdOnly){ 00505 SaveMain(); 00506 } 00507 } 00508 00509 TBlobPt TMBlobBs::PutBlob(const PSIn& SIn){ 00510 EAssert((Access==faCreate)||(Access==faUpdate)||(Access==faRestore)); 00511 TBlobPt BlobPt=SegV[CurSegN]->PutBlob(SIn); 00512 if (BlobPt.Empty()){ 00513 for (uchar SegN=0; SegN<SegV.Len(); SegN++){ 00514 BlobPt=SegV[CurSegN=SegN]->PutBlob(SIn); 00515 if (!BlobPt.Empty()){break;} 00516 } 00517 if (BlobPt.Empty()){ 00518 TStr SegFNm=GetSegFNm(NrFPath, NrFMid, SegV.Len()); 00519 PBlobBs Seg=TGBlobBs::New(SegFNm, faCreate, MxSegLen); 00520 CurSegN=SegV.Add(Seg); EAssert(CurSegN<=255); 00521 BlobPt=SegV[CurSegN]->PutBlob(SIn); 00522 } 00523 } 00524 if (!BlobPt.Empty()){ 00525 BlobPt.PutSeg(uchar(CurSegN));} 00526 return BlobPt; 00527 } 00528 00529 TBlobPt TMBlobBs::PutBlob(const TBlobPt& BlobPt, const PSIn& SIn){ 00530 EAssert((Access==faCreate)||(Access==faUpdate)||(Access==faRestore)); 00531 int SegN=BlobPt.GetSeg(); 00532 TBlobPt NewBlobPt=SegV[SegN]->PutBlob(BlobPt, SIn); 00533 if (NewBlobPt.Empty()){ 00534 NewBlobPt=PutBlob(SIn); 00535 } else { 00536 NewBlobPt.PutSeg(BlobPt.GetSeg()); 00537 } 00538 return NewBlobPt; 00539 } 00540 00541 PSIn TMBlobBs::GetBlob(const TBlobPt& BlobPt){ 00542 int SegN=BlobPt.GetSeg(); 00543 return SegV[SegN]->GetBlob(BlobPt); 00544 } 00545 00546 void TMBlobBs::DelBlob(const TBlobPt& BlobPt){ 00547 int SegN=BlobPt.GetSeg(); 00548 SegV[SegN]->DelBlob(BlobPt); 00549 } 00550 00551 TBlobPt TMBlobBs::GetFirstBlobPt(){ 00552 return SegV[0]->GetFirstBlobPt(); 00553 } 00554 00555 TBlobPt TMBlobBs::FFirstBlobPt(){ 00556 return SegV[0]->FFirstBlobPt(); 00557 } 00558 00559 bool TMBlobBs::FNextBlobPt(TBlobPt& TrvBlobPt, TBlobPt& BlobPt, PSIn& BlobSIn){ 00560 uchar SegN=TrvBlobPt.GetSeg(); 00561 if (SegV[SegN]->FNextBlobPt(TrvBlobPt, BlobPt, BlobSIn)){ 00562 TrvBlobPt.PutSeg(SegN); 00563 BlobPt.PutSeg(SegN); 00564 return true; 00565 } else 00566 if (SegN==SegV.Len()-1){ 00567 return false; 00568 } else { 00569 SegN++; 00570 TrvBlobPt=SegV[SegN]->FFirstBlobPt(); 00571 TrvBlobPt.PutSeg(SegN); 00572 return FNextBlobPt(TrvBlobPt, BlobPt, BlobSIn); 00573 } 00574 } 00575 00576 bool TMBlobBs::Exists(const TStr& BlobBsFNm){ 00577 TStr NrFPath; TStr NrFMid; GetNrFPathFMid(BlobBsFNm, NrFPath, NrFMid); 00578 TStr MainFNm=GetMainFNm(NrFPath, NrFMid); 00579 return TFile::Exists(MainFNm); 00580 }