00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TBranch.h"
00013
00014 #include "TBasket.h"
00015 #include "TBranchBrowsable.h"
00016 #include "TBrowser.h"
00017 #include "TClass.h"
00018 #include "TBufferFile.h"
00019 #include "TClonesArray.h"
00020 #include "TFile.h"
00021 #include "TLeaf.h"
00022 #include "TLeafB.h"
00023 #include "TLeafC.h"
00024 #include "TLeafD.h"
00025 #include "TLeafF.h"
00026 #include "TLeafI.h"
00027 #include "TLeafL.h"
00028 #include "TLeafO.h"
00029 #include "TLeafObject.h"
00030 #include "TLeafS.h"
00031 #include "TMessage.h"
00032 #include "TROOT.h"
00033 #include "TSystem.h"
00034 #include "TMath.h"
00035 #include "TTree.h"
00036 #include "TTreeCache.h"
00037 #include "TTreeCacheUnzip.h"
00038 #include "TVirtualPad.h"
00039
00040 #include <cstddef>
00041 #include <string.h>
00042 #include <stdio.h>
00043
00044 R__EXTERN TTree* gTree;
00045
00046 Int_t TBranch::fgCount = 0;
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 ClassImp(TBranch)
00065
00066
00067 TBranch::TBranch()
00068 : TNamed()
00069 , TAttFill(0, 1001)
00070 , fCompress(0)
00071 , fBasketSize(32000)
00072 , fEntryOffsetLen(1000)
00073 , fWriteBasket(0)
00074 , fEntryNumber(0)
00075 , fOffset(0)
00076 , fMaxBaskets(10)
00077 , fNBaskets(0)
00078 , fSplitLevel(0)
00079 , fNleaves(0)
00080 , fReadBasket(0)
00081 , fReadEntry(-1)
00082 , fEntries(0)
00083 , fFirstEntry(0)
00084 , fTotBytes(0)
00085 , fZipBytes(0)
00086 , fBranches()
00087 , fLeaves()
00088 , fBaskets(fMaxBaskets)
00089 , fBasketBytes(0)
00090 , fBasketEntry(0)
00091 , fBasketSeek(0)
00092 , fTree(0)
00093 , fMother(0)
00094 , fParent(0)
00095 , fAddress(0)
00096 , fDirectory(0)
00097 , fFileName("")
00098 , fEntryBuffer(0)
00099 , fBrowsables(0)
00100 , fSkipZip(kFALSE)
00101 , fReadLeaves(&TBranch::ReadLeavesImpl)
00102 {
00103
00104
00105 }
00106
00107
00108 TBranch::TBranch(TTree *tree, const char* name, void* address, const char* leaflist, Int_t basketsize, Int_t compress)
00109 : TNamed(name, leaflist)
00110 , TAttFill(0, 1001)
00111 , fCompress(compress)
00112 , fBasketSize((basketsize < 100) ? 100 : basketsize)
00113 , fEntryOffsetLen(0)
00114 , fWriteBasket(0)
00115 , fEntryNumber(0)
00116 , fOffset(0)
00117 , fMaxBaskets(10)
00118 , fNBaskets(0)
00119 , fSplitLevel(0)
00120 , fNleaves(0)
00121 , fReadBasket(0)
00122 , fReadEntry(-1)
00123 , fEntries(0)
00124 , fFirstEntry(0)
00125 , fTotBytes(0)
00126 , fZipBytes(0)
00127 , fBranches()
00128 , fLeaves()
00129 , fBaskets(fMaxBaskets)
00130 , fBasketBytes(0)
00131 , fBasketEntry(0)
00132 , fBasketSeek(0)
00133 , fTree(tree)
00134 , fMother(0)
00135 , fParent(0)
00136 , fAddress((char*) address)
00137 , fDirectory(fTree->GetDirectory())
00138 , fFileName("")
00139 , fEntryBuffer(0)
00140 , fBrowsables(0)
00141 , fSkipZip(kFALSE)
00142 , fReadLeaves(&TBranch::ReadLeavesImpl)
00143 {
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 Init(name,leaflist,compress);
00198 }
00199
00200
00201 TBranch::TBranch(TBranch *parent, const char* name, void* address, const char* leaflist, Int_t basketsize, Int_t compress)
00202 : TNamed(name, leaflist)
00203 , TAttFill(0, 1001)
00204 , fCompress(compress)
00205 , fBasketSize((basketsize < 100) ? 100 : basketsize)
00206 , fEntryOffsetLen(0)
00207 , fWriteBasket(0)
00208 , fEntryNumber(0)
00209 , fOffset(0)
00210 , fMaxBaskets(10)
00211 , fNBaskets(0)
00212 , fSplitLevel(0)
00213 , fNleaves(0)
00214 , fReadBasket(0)
00215 , fReadEntry(-1)
00216 , fEntries(0)
00217 , fFirstEntry(0)
00218 , fTotBytes(0)
00219 , fZipBytes(0)
00220 , fBranches()
00221 , fLeaves()
00222 , fBaskets(fMaxBaskets)
00223 , fBasketBytes(0)
00224 , fBasketEntry(0)
00225 , fBasketSeek(0)
00226 , fTree(parent ? parent->GetTree() : 0)
00227 , fMother(parent ? parent->GetMother() : 0)
00228 , fParent(parent)
00229 , fAddress((char*) address)
00230 , fDirectory(fTree ? fTree->GetDirectory() : 0)
00231 , fFileName("")
00232 , fEntryBuffer(0)
00233 , fBrowsables(0)
00234 , fSkipZip(kFALSE)
00235 , fReadLeaves(&TBranch::ReadLeavesImpl)
00236 {
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 Init(name,leaflist,compress);
00280 }
00281
00282 void TBranch::Init(const char* name, const char* leaflist, Int_t compress)
00283 {
00284
00285
00286 if ((compress == -1) && fTree->GetDirectory()) {
00287 TFile* bfile = fTree->GetDirectory()->GetFile();
00288 if (bfile) {
00289 fCompress = bfile->GetCompressionLevel();
00290 }
00291 }
00292
00293 fBasketBytes = new Int_t[fMaxBaskets];
00294 fBasketEntry = new Long64_t[fMaxBaskets];
00295 fBasketSeek = new Long64_t[fMaxBaskets];
00296
00297 for (Int_t i = 0; i < fMaxBaskets; ++i) {
00298 fBasketBytes[i] = 0;
00299 fBasketEntry[i] = 0;
00300 fBasketSeek[i] = 0;
00301 }
00302
00303
00304
00305
00306
00307 char* nameBegin = const_cast<char*>(leaflist);
00308 Int_t offset = 0;
00309
00310 char* leafname = new char[640];
00311 char* leaftype = new char[320];
00312
00313 strlcpy(leaftype, "F",320);
00314 char* pos = const_cast<char*>(leaflist);
00315 const char* leaflistEnd = leaflist + strlen(leaflist);
00316 for (; pos <= leaflistEnd; ++pos) {
00317
00318 if ((*pos == ':') || (*pos == 0)) {
00319
00320 Int_t lenName = pos - nameBegin;
00321 char* ctype = 0;
00322 if (lenName) {
00323 strncpy(leafname, nameBegin, lenName);
00324 leafname[lenName] = 0;
00325 ctype = strstr(leafname, "/");
00326 if (ctype) {
00327 *ctype = 0;
00328 strlcpy(leaftype, ctype + 1,320);
00329 }
00330 }
00331 if (lenName == 0 || ctype == leafname) {
00332 Warning("TBranch","No name was given to the leaf number '%d' in the leaflist of the branch '%s'.",fNleaves,name);
00333 snprintf(leafname,640,"__noname%d",fNleaves);
00334 }
00335 TLeaf* leaf = 0;
00336 if (*leaftype == 'C') {
00337 leaf = new TLeafC(this, leafname, leaftype);
00338 } else if (*leaftype == 'O') {
00339 leaf = new TLeafO(this, leafname, leaftype);
00340 } else if (*leaftype == 'B') {
00341 leaf = new TLeafB(this, leafname, leaftype);
00342 } else if (*leaftype == 'b') {
00343 leaf = new TLeafB(this, leafname, leaftype);
00344 leaf->SetUnsigned();
00345 } else if (*leaftype == 'S') {
00346 leaf = new TLeafS(this, leafname, leaftype);
00347 } else if (*leaftype == 's') {
00348 leaf = new TLeafS(this, leafname, leaftype);
00349 leaf->SetUnsigned();
00350 } else if (*leaftype == 'I') {
00351 leaf = new TLeafI(this, leafname, leaftype);
00352 } else if (*leaftype == 'i') {
00353 leaf = new TLeafI(this, leafname, leaftype);
00354 leaf->SetUnsigned();
00355 } else if (*leaftype == 'F') {
00356 leaf = new TLeafF(this, leafname, leaftype);
00357 } else if (*leaftype == 'f') {
00358 leaf = new TLeafF(this, leafname, leaftype);
00359 } else if (*leaftype == 'L') {
00360 leaf = new TLeafL(this, leafname, leaftype);
00361 } else if (*leaftype == 'l') {
00362 leaf = new TLeafL(this, leafname, leaftype);
00363 leaf->SetUnsigned();
00364 } else if (*leaftype == 'D') {
00365 leaf = new TLeafD(this, leafname, leaftype);
00366 } else if (*leaftype == 'd') {
00367 leaf = new TLeafD(this, leafname, leaftype);
00368 }
00369 if (!leaf) {
00370 Error("TLeaf", "Illegal data type for %s/%s", name, leaflist);
00371 delete[] leaftype;
00372 delete [] leafname;
00373 MakeZombie();
00374 return;
00375 }
00376 if (leaf->IsZombie()) {
00377 delete leaf;
00378 leaf = 0;
00379 Error("TBranch", "Illegal leaf: %s/%s", name, leaflist);
00380 delete [] leafname;
00381 delete[] leaftype;
00382 MakeZombie();
00383 return;
00384 }
00385 leaf->SetBranch(this);
00386 leaf->SetAddress((char*) (fAddress + offset));
00387 leaf->SetOffset(offset);
00388 if (leaf->GetLeafCount()) {
00389
00390 fEntryOffsetLen = 1000;
00391 }
00392 if (leaf->InheritsFrom(TLeafC::Class())) {
00393
00394 fEntryOffsetLen = 1000;
00395 }
00396 ++fNleaves;
00397 fLeaves.Add(leaf);
00398 fTree->GetListOfLeaves()->Add(leaf);
00399 if (*pos == 0) {
00400
00401 break;
00402 }
00403 nameBegin = pos + 1;
00404 offset += leaf->GetLenType() * leaf->GetLen();
00405 }
00406 }
00407 delete[] leafname;
00408 leafname = 0;
00409 delete[] leaftype;
00410 leaftype = 0;
00411
00412 }
00413
00414
00415 TBranch::~TBranch()
00416 {
00417
00418
00419 delete fBrowsables;
00420 fBrowsables = 0;
00421
00422
00423 fEntryBuffer = 0;
00424
00425 delete [] fBasketSeek;
00426 fBasketSeek = 0;
00427
00428 delete [] fBasketEntry;
00429 fBasketEntry = 0;
00430
00431 delete [] fBasketBytes;
00432 fBasketBytes = 0;
00433
00434 fBaskets.Delete();
00435 fNBaskets = 0;
00436
00437
00438 if (fTree) {
00439 TObjArray* lst = fTree->GetListOfLeaves();
00440 if (lst && lst->GetLast()!=-1) {
00441 lst->RemoveAll(&fLeaves);
00442 }
00443 }
00444
00445 fLeaves.Delete();
00446
00447 fBranches.Delete();
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 if (fDirectory && (!fTree || fDirectory != fTree->GetDirectory())) {
00462 TString bFileName( GetRealFileName() );
00463
00464 TFile* file = (TFile*)gROOT->GetListOfFiles()->FindObject(bFileName);
00465 if (file){
00466 file->Close();
00467 delete file;
00468 file = 0;
00469 }
00470 }
00471
00472 fTree = 0;
00473 fDirectory = 0;
00474 }
00475
00476
00477 void TBranch::AddBasket(TBasket& b, Bool_t ondisk, Long64_t startEntry)
00478 {
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488 TBasket *basket = &b;
00489
00490 basket->SetBranch(this);
00491
00492 if (fWriteBasket >= fMaxBaskets) {
00493 ExpandBasketArrays();
00494 }
00495 Int_t where = fWriteBasket;
00496
00497 if (where && startEntry < fBasketEntry[where-1]) {
00498
00499
00500 if (!ondisk) {
00501 Warning("AddBasket","The assumption that out-of-order basket only comes from disk based ntuple is false.");
00502 }
00503
00504 if (startEntry < fBasketEntry[0]) {
00505 where = 0;
00506 } else {
00507 for(Int_t i=fWriteBasket-1; i>=0; --i) {
00508 if (fBasketEntry[i] < startEntry) {
00509 where = i+1;
00510 break;
00511 } else if (fBasketEntry[i] == startEntry) {
00512 Error("AddBasket","An out-of-order basket matches the entry number of an existing basket.");
00513 }
00514 }
00515 }
00516
00517 if (where < fWriteBasket) {
00518
00519 for (Int_t j=fWriteBasket; j > where; --j) {
00520 fBasketEntry[j] = fBasketEntry[j-1];
00521 fBasketBytes[j] = fBasketBytes[j-1];
00522 fBasketSeek[j] = fBasketSeek[j-1];
00523 }
00524 }
00525 }
00526 fBasketEntry[where] = startEntry;
00527
00528 if (ondisk) {
00529 fBasketBytes[where] = basket->GetNbytes();
00530 fBasketSeek[where] = basket->GetSeekKey();
00531 fBaskets.AddAtAndExpand(0,fWriteBasket);
00532 ++fWriteBasket;
00533 } else {
00534 ++fNBaskets;
00535 fBaskets.AddAtAndExpand(basket,fWriteBasket);
00536 fTree->IncrementTotalBuffers(basket->GetBufferSize());
00537 }
00538
00539 fEntries += basket->GetNevBuf();
00540 fEntryNumber += basket->GetNevBuf();
00541 if (ondisk) {
00542 fTotBytes += basket->GetObjlen() + basket->GetKeylen() ;
00543 fZipBytes += basket->GetNbytes();
00544 fTree->AddTotBytes(basket->GetObjlen() + basket->GetKeylen());
00545 fTree->AddZipBytes(basket->GetNbytes());
00546 }
00547 }
00548
00549
00550 void TBranch::AddLastBasket(Long64_t startEntry)
00551 {
00552
00553
00554 if (fWriteBasket >= fMaxBaskets) {
00555 ExpandBasketArrays();
00556 }
00557 Int_t where = fWriteBasket;
00558
00559 if (where && startEntry < fBasketEntry[where-1]) {
00560
00561
00562 Fatal("AddBasket","The last basket must have the highest entry number (%s/%lld/%d).",GetName(),startEntry,fWriteBasket);
00563
00564 }
00565 fBasketEntry[where] = startEntry;
00566 fBaskets.AddAtAndExpand(0,fWriteBasket);
00567 }
00568
00569
00570 void TBranch::Browse(TBrowser* b)
00571 {
00572
00573
00574 if (fNleaves > 1) {
00575 fLeaves.Browse(b);
00576 } else {
00577
00578
00579 TString name = GetName();
00580 Int_t pos = name.First('[');
00581 if (pos!=kNPOS) name.Remove(pos);
00582
00583 GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
00584 if (gPad) gPad->Update();
00585 }
00586 }
00587
00588
00589 void TBranch::DeleteBaskets(Option_t* option)
00590 {
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 TString opt = option;
00601 opt.ToLower();
00602 TFile *file = GetFile(0);
00603
00604 if(fDirectory && (fDirectory != gROOT) && fDirectory->IsWritable()) {
00605 for(Int_t i=0; i<fWriteBasket; i++) {
00606 if (fBasketSeek[i]) file->MakeFree(fBasketSeek[i],fBasketSeek[i]+fBasketBytes[i]-1);
00607 }
00608 }
00609
00610
00611 if (opt.Contains("all")) {
00612 TObjArray *lb = GetListOfBranches();
00613 Int_t nb = lb->GetEntriesFast();
00614 for (Int_t j = 0; j < nb; j++) {
00615 TBranch* branch = (TBranch*) lb->UncheckedAt(j);
00616 if (branch) branch->DeleteBaskets("all");
00617 }
00618 }
00619 DropBaskets("all");
00620 Reset();
00621 }
00622
00623
00624 void TBranch::DropBaskets(Option_t* options)
00625 {
00626
00627
00628
00629
00630
00631 Bool_t all = kFALSE;
00632 if (options && options[0]) {
00633 TString opt = options;
00634 opt.ToLower();
00635 if (opt.Contains("all")) all = kTRUE;
00636 }
00637
00638 TBasket *basket;
00639 Int_t nbaskets = fBaskets.GetEntriesFast();
00640
00641 if ( (fNBaskets>1) || all ) {
00642
00643 for (Int_t i=0;i<nbaskets;i++) {
00644 basket = (TBasket*)fBaskets.UncheckedAt(i);
00645 if (!basket) continue;
00646 if ((i == fReadBasket || i == fWriteBasket) && !all) continue;
00647 if (fBasketBytes[i]==0) continue;
00648 basket->DropBuffers();
00649 --fNBaskets;
00650 fBaskets.RemoveAt(i);
00651 delete basket;
00652 }
00653
00654
00655 if (all) {
00656 TObjArray *lb = GetListOfBranches();
00657 Int_t nb = lb->GetEntriesFast();
00658 for (Int_t j = 0; j < nb; j++) {
00659 TBranch* branch = (TBranch*) lb->UncheckedAt(j);
00660 if (!branch) continue;
00661 branch->DropBaskets("all");
00662 }
00663 }
00664 } else {
00665
00666 if (nbaskets > 0) {
00667 Int_t i = fBaskets.GetLast();
00668 basket = (TBasket*)fBaskets.UncheckedAt(i);
00669 if (basket && fBasketBytes[i]!=0) {
00670 basket->DropBuffers();
00671 delete basket;
00672 fBaskets.AddAt(0,i);
00673 fBaskets.SetLast(-1);
00674 fNBaskets = 0;
00675 }
00676 }
00677 }
00678
00679 }
00680
00681
00682 void TBranch::ExpandBasketArrays()
00683 {
00684
00685
00686
00687 Int_t newsize = TMath::Max(10,Int_t(1.5*fMaxBaskets));
00688 fBasketBytes = TStorage::ReAllocInt(fBasketBytes, newsize, fMaxBaskets);
00689 fBasketEntry = (Long64_t*)TStorage::ReAlloc(fBasketEntry,
00690 newsize*sizeof(Long64_t),fMaxBaskets*sizeof(Long64_t));
00691 fBasketSeek = (Long64_t*)TStorage::ReAlloc(fBasketSeek,
00692 newsize*sizeof(Long64_t),fMaxBaskets*sizeof(Long64_t));
00693
00694 fMaxBaskets = newsize;
00695
00696 fBaskets.Expand(newsize);
00697
00698 for (Int_t i=fWriteBasket;i<fMaxBaskets;i++) {
00699 fBasketBytes[i] = 0;
00700 fBasketEntry[i] = 0;
00701 fBasketSeek[i] = 0;
00702 }
00703 }
00704
00705
00706 Int_t TBranch::Fill()
00707 {
00708
00709
00710
00711
00712
00713
00714
00715
00716 if (TestBit(kDoNotProcess)) {
00717 return 0;
00718 }
00719
00720 TBasket* basket = GetBasket(fWriteBasket);
00721 if (!basket) {
00722 basket = fTree->CreateBasket(this);
00723 if (!basket) return 0;
00724 ++fNBaskets;
00725 fBaskets.AddAtAndExpand(basket,fWriteBasket);
00726 }
00727 TBuffer* buf = basket->GetBufferRef();
00728
00729
00730
00731 Int_t nsize = 0;
00732
00733 if (buf->IsReading()) {
00734 basket->SetWriteMode();
00735 }
00736
00737 buf->ResetMap();
00738
00739 Int_t lold = buf->Length();
00740 Int_t objectStart = 0;
00741 Int_t last = 0;
00742 Int_t lnew = 0;
00743 Int_t nbytes = 0;
00744
00745 if (fEntryBuffer) {
00746 if (fEntryBuffer->IsA() == TMessage::Class()) {
00747 objectStart = 8;
00748 }
00749 if (fEntryBuffer->TestBit(TBufferFile::kNotDecompressed)) {
00750
00751 if (basket->GetNevBuf()) {
00752
00753
00754
00755 WriteBasket(basket,fWriteBasket);
00756
00757 return Fill();
00758 }
00759 Int_t startpos = fEntryBuffer->Length();
00760 fEntryBuffer->SetBufferOffset(0);
00761 static TBasket toread_fLast;
00762 fEntryBuffer->SetReadMode();
00763 toread_fLast.Streamer(*fEntryBuffer);
00764 fEntryBuffer->SetWriteMode();
00765 last = toread_fLast.GetLast();
00766
00767 fEntryBuffer->SetBufferOffset(startpos);
00768 buf->SetBufferOffset(0);
00769 buf->SetBit(TBufferFile::kNotDecompressed);
00770 basket->Update(lold);
00771 } else {
00772
00773
00774
00775 const UInt_t kNewClassTag = 0xFFFFFFFF;
00776 const UInt_t kByteCountMask = 0x40000000;
00777 UInt_t tag = 0;
00778 UInt_t startpos = fEntryBuffer->Length();
00779 fEntryBuffer->SetBufferOffset(objectStart);
00780 *fEntryBuffer >> tag;
00781 if (tag & kByteCountMask) {
00782 *fEntryBuffer >> tag;
00783 }
00784 if (tag == kNewClassTag) {
00785 UInt_t maxsize = 256;
00786 char* s = new char[maxsize];
00787 Int_t name_start = fEntryBuffer->Length();
00788 fEntryBuffer->ReadString(s, maxsize);
00789 while (strlen(s) == (maxsize - 1)) {
00790
00791 fEntryBuffer->SetBufferOffset(name_start);
00792 maxsize *= 2;
00793 delete[] s;
00794 s = new char[maxsize];
00795 fEntryBuffer->ReadString(s, maxsize);
00796 }
00797 } else {
00798 fEntryBuffer->SetBufferOffset(objectStart);
00799 }
00800 objectStart = fEntryBuffer->Length();
00801 fEntryBuffer->SetBufferOffset(startpos);
00802 basket->Update(lold, objectStart - fEntryBuffer->GetBufferDisplacement());
00803 }
00804 fEntries++;
00805 fEntryNumber++;
00806 UInt_t len = 0;
00807 UInt_t startpos = fEntryBuffer->Length();
00808 if (startpos > UInt_t(objectStart)) {
00809
00810
00811 len = fEntryBuffer->Length() - objectStart;
00812 } else {
00813
00814
00815
00816
00817 len = fEntryBuffer->BufferSize() - objectStart;
00818 }
00819 buf->WriteBuf(fEntryBuffer->Buffer() + objectStart, len);
00820 if (fEntryBuffer->TestBit(TBufferFile::kNotDecompressed)) {
00821
00822
00823
00824 nbytes = last;
00825 lnew = last;
00826 } else {
00827 lnew = buf->Length();
00828 nbytes = lnew - lold;
00829 }
00830 } else {
00831 basket->Update(lold);
00832 ++fEntries;
00833 ++fEntryNumber;
00834 FillLeaves(*buf);
00835 lnew = buf->Length();
00836 nbytes = lnew - lold;
00837 }
00838
00839 if (fEntryOffsetLen) {
00840 Int_t nevbuf = basket->GetNevBuf();
00841
00842 nsize = nevbuf * sizeof(Int_t);
00843 } else {
00844 if (!basket->GetNevBufSize()) {
00845 basket->SetNevBufSize(nbytes);
00846 }
00847 }
00848
00849
00850
00851
00852
00853 if ((fSkipZip && (lnew >= TBuffer::kMinimalSize)) || (buf->TestBit(TBufferFile::kNotDecompressed)) || ((lnew + (2 * nsize) + nbytes) >= fBasketSize)) {
00854 if (fTree->TestBit(TTree::kCircular)) {
00855 return nbytes;
00856 }
00857 Int_t nevbuf = basket->GetNevBuf();
00858 if (fEntryOffsetLen > 10 && (4*nevbuf) < fEntryOffsetLen ) {
00859 fEntryOffsetLen = nevbuf < 3 ? 10 : 4*nevbuf;
00860 } else if (fEntryOffsetLen && nevbuf > fEntryOffsetLen) {
00861 fEntryOffsetLen = 2*nevbuf;
00862 }
00863 Int_t nout = WriteBasket(basket,fWriteBasket);
00864 return (nout >= 0) ? nbytes : -1;
00865 }
00866 return nbytes;
00867 }
00868
00869
00870 void TBranch::FillLeaves(TBuffer& b)
00871 {
00872
00873
00874 for (Int_t i = 0; i < fNleaves; ++i) {
00875 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
00876 leaf->FillBasket(b);
00877 }
00878 }
00879
00880
00881 TBranch* TBranch::FindBranch(const char* name)
00882 {
00883
00884
00885
00886 std::string longnm;
00887 longnm.reserve(fName.Length()+strlen(name)+3);
00888 longnm = fName.Data();
00889 if (longnm[longnm.length()-1]==']') {
00890 std::size_t dim = longnm.find_first_of("[");
00891 if (dim != std::string::npos) {
00892 longnm.erase(dim);
00893 }
00894 }
00895 if (longnm[longnm.length()-1] != '.') {
00896 longnm += '.';
00897 }
00898 longnm += name;
00899 UInt_t namelen = strlen(name);
00900
00901 Int_t nbranches = fBranches.GetEntries();
00902 TBranch* branch = 0;
00903 for(Int_t i = 0; i < nbranches; ++i) {
00904 branch = (TBranch*) fBranches.UncheckedAt(i);
00905
00906 const char *brname = branch->fName.Data();
00907 UInt_t brlen = branch->fName.Length();
00908 if (brname[brlen-1]==']') {
00909 const char *dim = strchr(brname,'[');
00910 if (dim) {
00911 brlen = dim - brname;
00912 }
00913 }
00914 if (namelen == brlen
00915 && strncmp(name,brname,brlen) == 0) {
00916 return branch;
00917 }
00918 if (brlen == (size_t)longnm.length()
00919 && strncmp(longnm.c_str(),brname,brlen) == 0) {
00920 return branch;
00921 }
00922 }
00923 return 0;
00924 }
00925
00926
00927 TLeaf* TBranch::FindLeaf(const char* searchname)
00928 {
00929
00930
00931 TString leafname;
00932 TString leaftitle;
00933 TString longname;
00934 TString longtitle;
00935
00936
00937 TIter next(GetListOfLeaves());
00938 TLeaf* leaf = 0;
00939 while ((leaf = (TLeaf*) next())) {
00940 leafname = leaf->GetName();
00941 Ssiz_t dim = leafname.First('[');
00942 if (dim >= 0) leafname.Remove(dim);
00943
00944 if (leafname == searchname) return leaf;
00945
00946
00947 leaftitle = leaf->GetTitle();
00948 dim = leaftitle.First('[');
00949 if (dim >= 0) leaftitle.Remove(dim);
00950
00951 if (leaftitle == searchname) return leaf;
00952
00953 TBranch* branch = leaf->GetBranch();
00954 if (branch) {
00955 longname.Form("%s.%s",branch->GetName(),leafname.Data());
00956 dim = longname.First('[');
00957 if (dim>=0) longname.Remove(dim);
00958 if (longname == searchname) return leaf;
00959
00960
00961 longname.Form("%s.%s",branch->GetName(),searchname);
00962 if (longname==leafname) return leaf;
00963
00964 longtitle.Form("%s.%s",branch->GetName(),leaftitle.Data());
00965 dim = longtitle.First('[');
00966 if (dim>=0) longtitle.Remove(dim);
00967 if (longtitle == searchname) return leaf;
00968
00969
00970
00971
00972
00973
00974 if (strstr(searchname, ".") && !strcmp(searchname, branch->GetName())) return leaf;
00975 }
00976 }
00977 return 0;
00978 }
00979
00980
00981
00982 Int_t TBranch::FlushBaskets()
00983 {
00984
00985
00986
00987 UInt_t nerror = 0;
00988 Int_t nbytes = 0;
00989
00990 Int_t maxbasket = fWriteBasket + 1;
00991
00992
00993
00994
00995
00996 for(Int_t i=0; i != maxbasket; ++i) {
00997 if (fBaskets.UncheckedAt(i)) {
00998 Int_t nwrite = FlushOneBasket(i);
00999 if (nwrite<0) {
01000 ++nerror;
01001 } else {
01002 nbytes += nwrite;
01003 }
01004 }
01005 }
01006 Int_t len = fBranches.GetEntriesFast();
01007 for (Int_t i = 0; i < len; ++i) {
01008 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
01009 if (!branch) {
01010 continue;
01011 }
01012 Int_t nwrite = branch->FlushBaskets();
01013 if (nwrite<0) {
01014 ++nerror;
01015 } else {
01016 nbytes += nwrite;
01017 }
01018 }
01019 if (nerror) {
01020 return -1;
01021 } else {
01022 return nbytes;
01023 }
01024 }
01025
01026
01027 Int_t TBranch::FlushOneBasket(UInt_t ibasket)
01028 {
01029
01030
01031
01032
01033 Int_t nbytes = 0;
01034 if (fDirectory && fBaskets.GetEntries()) {
01035 TBasket *basket = (TBasket*)fBaskets.UncheckedAt(ibasket);
01036
01037 if (basket) {
01038 if (basket->GetNevBuf()
01039 && fBasketSeek[ibasket]==0) {
01040
01041
01042
01043 if (basket->GetBufferRef()->IsReading()) {
01044 basket->SetWriteMode();
01045 }
01046 nbytes = WriteBasket(basket,ibasket);
01047
01048 } else {
01049
01050 if ((Int_t)ibasket==fWriteBasket) {
01051
01052 } else {
01053 basket->DropBuffers();
01054 delete basket;
01055 --fNBaskets;
01056 fBaskets[ibasket] = 0;
01057 }
01058 }
01059 }
01060 }
01061 return nbytes;
01062 }
01063
01064
01065 TBasket* TBranch::GetBasket(Int_t basketnumber)
01066 {
01067
01068
01069
01070 static Int_t nerrors = 0;
01071
01072
01073 if (basketnumber <0 || basketnumber > fWriteBasket) return 0;
01074 TBasket *basket = (TBasket*)fBaskets.UncheckedAt(basketnumber);
01075 if (basket) return basket;
01076 if (basketnumber == fWriteBasket) return 0;
01077
01078
01079 TFile *file = GetFile(0);
01080 if (file == 0) {
01081 return 0;
01082 }
01083 basket = GetFreshBasket();
01084
01085
01086 if (fSkipZip) basket->SetBit(TBufferFile::kNotDecompressed);
01087 if (fBasketBytes[basketnumber] == 0) {
01088 fBasketBytes[basketnumber] = basket->ReadBasketBytes(fBasketSeek[basketnumber],file);
01089 }
01090
01091 TFileCacheRead *pf = file->GetCacheRead();
01092 if (pf){
01093 if (pf->IsLearning()) pf->AddBranch(this);
01094 if (fSkipZip) pf->SetSkipZip();
01095 }
01096
01097
01098 Int_t badread = basket->ReadBasketBuffers(fBasketSeek[basketnumber],fBasketBytes[basketnumber],file);
01099 if (badread || basket->GetSeekKey() != fBasketSeek[basketnumber]) {
01100 nerrors++;
01101 if (nerrors > 10) return 0;
01102 if (nerrors == 10) {
01103 printf(" file probably overwritten: stopping reporting error messages\n");
01104 if (fBasketSeek[basketnumber] > 2000000000) {
01105 printf("===>File is more than 2 Gigabytes\n");
01106 return 0;
01107 }
01108 if (fBasketSeek[basketnumber] > 1000000000) {
01109 printf("===>Your file is may be bigger than the maximum file size allowed on your system\n");
01110 printf(" Check your AFS maximum file size limit for example\n");
01111 return 0;
01112 }
01113 }
01114 Error("GetBasket","File: %s at byte:%lld, branch:%s, entry:%lld, badread=%d, nerrors=%d, basketnumber=%d",file->GetName(),basket->GetSeekKey(),GetName(),fReadEntry,badread,nerrors,basketnumber);
01115 return 0;
01116 }
01117
01118 ++fNBaskets;
01119 fBaskets.AddAt(basket,basketnumber);
01120 return basket;
01121 }
01122
01123
01124 Long64_t TBranch::GetBasketSeek(Int_t basketnumber) const
01125 {
01126
01127
01128
01129 if (basketnumber <0 || basketnumber > fWriteBasket) return 0;
01130 return fBasketSeek[basketnumber];
01131 }
01132
01133
01134 TList* TBranch::GetBrowsables() {
01135
01136
01137 if (fBrowsables) return fBrowsables;
01138 fBrowsables=new TList();
01139 TVirtualBranchBrowsable::FillListOfBrowsables(*fBrowsables, this);
01140 return fBrowsables;
01141 }
01142
01143
01144 const char * TBranch::GetClassName() const
01145 {
01146
01147
01148
01149
01150 return "";
01151 }
01152
01153
01154 const char* TBranch::GetIconName() const
01155 {
01156
01157
01158 if (IsFolder())
01159 return "TBranchElement-folder";
01160 else
01161 return "TBranchElement-leaf";
01162 }
01163
01164
01165 Int_t TBranch::GetEntry(Long64_t entry, Int_t getall)
01166 {
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184 if (TestBit(kDoNotProcess) && !getall) {
01185 return 0;
01186 }
01187 if ((entry < fFirstEntry) || (entry >= fEntryNumber)) {
01188 return 0;
01189 }
01190 Int_t nbytes = 0;
01191 Long64_t first = fBasketEntry[fReadBasket];
01192 Long64_t last = 0;
01193 if (fReadBasket == fWriteBasket) {
01194 last = fEntryNumber - 1;
01195 } else {
01196 last = fBasketEntry[fReadBasket+1] - 1;
01197 }
01198
01199 if ((entry < first) || (entry > last)) {
01200 fReadBasket = TMath::BinarySearch(fWriteBasket + 1, fBasketEntry, entry);
01201 if (fReadBasket < 0) {
01202 Error("In the branch %s, no basket contains the entry %d\n", GetName(), entry);
01203 return -1;
01204 }
01205 first = fBasketEntry[fReadBasket];
01206 }
01207
01208
01209 TBasket* basket = (TBasket*) fBaskets.UncheckedAt(fReadBasket);
01210 if (!basket) {
01211 basket = GetBasket(fReadBasket);
01212 if (!basket) {
01213 return -1;
01214 }
01215 }
01216 basket->PrepareBasket(entry);
01217 TBuffer* buf = basket->GetBufferRef();
01218
01219 if (!buf) {
01220 TFile* file = GetFile(0);
01221 basket->ReadBasketBuffers(fBasketSeek[fReadBasket], fBasketBytes[fReadBasket], file);
01222 buf = basket->GetBufferRef();
01223 }
01224
01225 buf->ResetMap();
01226 if (!buf->IsReading()) {
01227 basket->SetReadMode();
01228 }
01229 Int_t* entryOffset = basket->GetEntryOffset();
01230 Int_t bufbegin = 0;
01231 if (entryOffset) {
01232 bufbegin = entryOffset[entry-first];
01233 } else {
01234 bufbegin = basket->GetKeylen() + ((entry - first) * basket->GetNevBufSize());
01235 }
01236 buf->SetBufferOffset(bufbegin);
01237 Int_t* displacement = basket->GetDisplacement();
01238 if (displacement) {
01239 buf->SetBufferDisplacement(displacement[entry-first]);
01240 } else {
01241 buf->SetBufferDisplacement();
01242 }
01243
01244 fReadEntry = entry;
01245 (this->*fReadLeaves)(*buf);
01246 nbytes = buf->Length() - bufbegin;
01247 return nbytes;
01248 }
01249
01250
01251 Int_t TBranch::GetEntryExport(Long64_t entry, Int_t , TClonesArray* li, Int_t nentries)
01252 {
01253
01254
01255
01256
01257 if (TestBit(kDoNotProcess)) {
01258 return 0;
01259 }
01260 if ((entry < 0) || (entry >= fEntryNumber)) {
01261 return 0;
01262 }
01263 Int_t nbytes = 0;
01264 Long64_t first = fBasketEntry[fReadBasket];
01265 Long64_t last = 0;
01266 if (fReadBasket == fWriteBasket) {
01267 last = fEntryNumber - 1;
01268 } else {
01269 last = fBasketEntry[fReadBasket+1] - 1;
01270 }
01271
01272 if ((entry < first) || (entry > last)) {
01273 fReadBasket = TMath::BinarySearch(fWriteBasket + 1, fBasketEntry, entry);
01274 first = fBasketEntry[fReadBasket];
01275 }
01276
01277
01278
01279 TBasket* basket = GetBasket(fReadBasket);
01280 if (!basket) {
01281 return 0;
01282 }
01283 TBuffer* buf = basket->GetBufferRef();
01284
01285 if (!buf->IsReading()) {
01286 basket->SetReadMode();
01287 }
01288 Int_t bufbegin = 0;
01289 Int_t* entryOffset = basket->GetEntryOffset();
01290 if (entryOffset) {
01291 bufbegin = entryOffset[entry-first];
01292 } else {
01293 bufbegin = basket->GetKeylen() + ((entry - first) * basket->GetNevBufSize());
01294 }
01295 buf->SetBufferOffset(bufbegin);
01296 Int_t* displacement = basket->GetDisplacement();
01297 if (displacement) {
01298 buf->SetBufferDisplacement(displacement[entry-first]);
01299 } else {
01300 buf->SetBufferDisplacement();
01301 }
01302
01303 fReadEntry = entry;
01304 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(0);
01305 leaf->ReadBasketExport(*buf, li, nentries);
01306 nbytes = buf->Length() - bufbegin;
01307 return nbytes;
01308 }
01309
01310
01311 Int_t TBranch::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
01312 {
01313
01314
01315
01316
01317
01318 expectedClass = 0;
01319 expectedType = kOther_t;
01320 TLeaf* l = (TLeaf*) GetListOfLeaves()->At(0);
01321 if (l) {
01322 expectedType = (EDataType) gROOT->GetType(l->GetTypeName())->GetType();
01323 return 0;
01324 } else {
01325 Error("GetExpectedType", "Did not find any leaves in %s",GetName());
01326 return 1;
01327 }
01328 }
01329
01330
01331 TFile* TBranch::GetFile(Int_t mode)
01332 {
01333
01334
01335
01336
01337 if (fDirectory) return fDirectory->GetFile();
01338
01339
01340 TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(fFileName.Data());
01341 if (file) {
01342 fDirectory = file;
01343 return file;
01344 }
01345
01346 if (fFileName.Length() == 0) return 0;
01347
01348 TString bFileName( GetRealFileName() );
01349
01350
01351 {
01352 TDirectory::TContext ctxt(0);
01353 if (mode) file = TFile::Open(bFileName, "recreate");
01354 else file = TFile::Open(bFileName);
01355 }
01356 if (!file) return 0;
01357 if (file->IsZombie()) {delete file; return 0;}
01358 fDirectory = (TDirectory*)file;
01359 return file;
01360 }
01361
01362
01363 TBasket* TBranch::GetFreshBasket()
01364 {
01365
01366
01367
01368 TBasket *basket = 0;
01369 if (GetTree()->MemoryFull(0)) {
01370 if (fNBaskets==1) {
01371
01372 Int_t oldindex = fBaskets.GetLast();
01373 basket = (TBasket*)fBaskets.UncheckedAt(oldindex);
01374 if (!basket) {
01375 fBaskets.SetLast(-2);
01376 oldindex = fBaskets.GetLast();
01377 basket = (TBasket*)fBaskets.UncheckedAt(oldindex);
01378 }
01379 if (basket && fBasketBytes[oldindex]!=0) {
01380 fBaskets.AddAt(0,oldindex);
01381 fBaskets.SetLast(-1);
01382 fNBaskets = 0;
01383 } else {
01384 basket = fTree->CreateBasket(this);
01385 }
01386 } else if (fNBaskets == 0) {
01387
01388 basket = fTree->CreateBasket(this);
01389 } else {
01390
01391
01392 DropBaskets();
01393 basket = fTree->CreateBasket(this);
01394 }
01395 } else {
01396 basket = fTree->CreateBasket(this);
01397 }
01398 return basket;
01399 }
01400
01401
01402 TLeaf* TBranch::GetLeaf(const char* name) const
01403 {
01404
01405
01406
01407 Int_t i;
01408 for (i=0;i<fNleaves;i++) {
01409 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
01410 if (!strcmp(leaf->GetName(),name)) return leaf;
01411 }
01412 return 0;
01413 }
01414
01415
01416 TString TBranch::GetRealFileName() const
01417 {
01418 if (fFileName.Length()==0) {
01419 return fFileName;
01420 }
01421 TString bFileName = fFileName;
01422
01423
01424
01425 char *bname = gSystem->ExpandPathName(fFileName.Data());
01426 if (!gSystem->IsAbsoluteFileName(bname) && !strstr(bname, ":/") && fTree && fTree->GetCurrentFile()) {
01427
01428
01429 const char *tfn = fTree->GetCurrentFile()->GetName();
01430
01431
01432 TUrl arc(tfn);
01433 if (strlen(arc.GetAnchor()) > 0) {
01434 arc.SetAnchor(gSystem->BaseName(fFileName));
01435 bFileName = arc.GetUrl();
01436 } else {
01437
01438
01439 char *tname = gSystem->ExpandPathName(tfn);
01440 if (gSystem->IsAbsoluteFileName(tname) || strstr(tname, ":/")) {
01441 bFileName = gSystem->DirName(tname);
01442 bFileName += "/";
01443 bFileName += fFileName;
01444 }
01445 delete [] tname;
01446 }
01447 }
01448 delete [] bname;
01449
01450 return bFileName;
01451 }
01452
01453
01454 Int_t TBranch::GetRow(Int_t)
01455 {
01456
01457
01458
01459 return 1;
01460 }
01461
01462
01463 Bool_t TBranch::GetMakeClass() const
01464 {
01465
01466
01467
01468
01469
01470 return kFALSE;
01471 }
01472
01473
01474 TBranch* TBranch::GetMother() const
01475 {
01476
01477
01478 if (fMother) return fMother;
01479
01480 const TObjArray* array = fTree->GetListOfBranches();
01481 Int_t n = array->GetEntriesFast();
01482 for (Int_t i = 0; i < n; ++i) {
01483 TBranch* branch = (TBranch*) array->UncheckedAt(i);
01484 TBranch* parent = branch->GetSubBranch(this);
01485 if (parent) {
01486 const_cast<TBranch*>(this)->fMother = branch;
01487 return branch;
01488 }
01489 }
01490 return 0;
01491 }
01492
01493
01494 TBranch* TBranch::GetSubBranch(const TBranch* child) const
01495 {
01496
01497
01498
01499
01500 if (this == child) {
01501
01502 return (TBranch*) this;
01503 }
01504
01505 if (child->fParent) {
01506 return child->fParent;
01507 }
01508
01509 Int_t len = fBranches.GetEntriesFast();
01510 for (Int_t i = 0; i < len; ++i) {
01511 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
01512 if (!branch) {
01513 continue;
01514 }
01515 if (branch == child) {
01516
01517 const_cast<TBranch*>(child)->fParent = (TBranch*)this;
01518
01519 const_cast<TBranch*>(child)->fParent = (TBranch*)this;
01520 return (TBranch*) this;
01521 }
01522
01523 TBranch* parent = branch->GetSubBranch(child);
01524 if (parent) {
01525 return parent;
01526 }
01527 }
01528
01529 return 0;
01530 }
01531
01532
01533 Long64_t TBranch::GetTotalSize(Option_t * ) const
01534 {
01535
01536
01537 TObjArray &baskets( const_cast<TObjArray&>(fBaskets) );
01538 TBasket *writebasket = 0;
01539 if (fNBaskets == 1) {
01540 writebasket = (TBasket*)fBaskets.UncheckedAt(fWriteBasket);
01541 if (writebasket && writebasket->GetNevBuf()==0) {
01542 baskets[fWriteBasket] = 0;
01543 } else {
01544 writebasket = 0;
01545 }
01546 }
01547 TBufferFile b(TBuffer::kWrite,10000);
01548 TBranch::Class()->WriteBuffer(b,(TBranch*)this);
01549 if (writebasket) {
01550 baskets[fWriteBasket] = writebasket;
01551 }
01552 Long64_t totbytes = 0;
01553 if (fZipBytes > 0) totbytes = fTotBytes;
01554 return totbytes + b.Length();
01555 }
01556
01557
01558 Long64_t TBranch::GetTotBytes(Option_t *option) const
01559 {
01560
01561
01562
01563 Long64_t totbytes = fTotBytes;
01564 if (!option) return totbytes;
01565 if (option[0] != '*') return totbytes;
01566
01567 Int_t len = fBranches.GetEntriesFast();
01568 for (Int_t i = 0; i < len; ++i) {
01569 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
01570 if (branch) totbytes += branch->GetTotBytes();
01571 }
01572 return totbytes;
01573 }
01574
01575
01576 Long64_t TBranch::GetZipBytes(Option_t *option) const
01577 {
01578
01579
01580
01581 Long64_t zipbytes = fZipBytes;
01582 if (!option) return zipbytes;
01583 if (option[0] != '*') return zipbytes;
01584
01585 Int_t len = fBranches.GetEntriesFast();
01586 for (Int_t i = 0; i < len; ++i) {
01587 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
01588 if (branch) zipbytes += branch->GetZipBytes();
01589 }
01590 return zipbytes;
01591 }
01592
01593
01594 Bool_t TBranch::IsAutoDelete() const
01595 {
01596
01597 return TestBit(kAutoDelete);
01598 }
01599
01600
01601 Bool_t TBranch::IsFolder() const
01602 {
01603
01604 if (fNleaves > 1) {
01605 return kTRUE;
01606 }
01607 TList* browsables = const_cast<TBranch*>(this)->GetBrowsables();
01608 return browsables && browsables->GetSize();
01609 }
01610
01611
01612 void TBranch::KeepCircular(Long64_t maxEntries)
01613 {
01614
01615
01616 Int_t dentries = (Int_t) (fEntries - maxEntries);
01617 TBasket* basket = (TBasket*) fBaskets.UncheckedAt(0);
01618 basket->MoveEntries(dentries);
01619 fEntries = maxEntries;
01620 fEntryNumber = maxEntries;
01621
01622 Int_t nb = fBranches.GetEntriesFast();
01623 for (Int_t i = 0; i < nb; ++i) {
01624 TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
01625 branch->KeepCircular(maxEntries);
01626 }
01627 }
01628
01629
01630 Int_t TBranch::LoadBaskets()
01631 {
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 Int_t nimported = 0;
01642 Int_t nbaskets = fWriteBasket;
01643 TFile *file = GetFile(0);
01644 TBasket *basket;
01645 for (Int_t i=0;i<nbaskets;i++) {
01646 basket = (TBasket*)fBaskets.UncheckedAt(i);
01647 if (basket) continue;
01648 basket = GetFreshBasket();
01649 if (fBasketBytes[i] == 0) {
01650 fBasketBytes[i] = basket->ReadBasketBytes(fBasketSeek[i],file);
01651 }
01652 Int_t badread = basket->ReadBasketBuffers(fBasketSeek[i],fBasketBytes[i],file);
01653 if (badread) {
01654 Error("Loadbaskets","Error while reading basket buffer %d of branch %s",i,GetName());
01655 return -1;
01656 }
01657 ++fNBaskets;
01658 fBaskets.AddAt(basket,i);
01659 nimported++;
01660 }
01661 return nimported;
01662 }
01663
01664
01665 void TBranch::Print(Option_t*) const
01666 {
01667
01668
01669 const int kLINEND = 77;
01670 Float_t cx = 1;
01671
01672 TString titleContent(GetTitle());
01673 if ( titleContent == GetName() ) {
01674 titleContent.Clear();
01675 }
01676
01677 if (fLeaves.GetEntries() == 1) {
01678 if (titleContent[titleContent.Length()-2]=='/' && isalpha(titleContent[titleContent.Length()-1])) {
01679
01680 } else {
01681 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
01682 if (titleContent.Length()) {
01683 titleContent.Prepend(" ");
01684 }
01685
01686 titleContent.Prepend(leaf->GetTypeName());
01687 }
01688 }
01689 Int_t titleLength = titleContent.Length();
01690
01691 Int_t aLength = titleLength + strlen(GetName());
01692 aLength += (aLength / 54 + 1) * 80 + 100;
01693 if (aLength < 200) aLength = 200;
01694 char *bline = new char[aLength];
01695
01696 Long64_t totBytes = GetTotalSize();
01697 if (fZipBytes) cx = (fTotBytes+0.00001)/fZipBytes;
01698 if (titleLength) snprintf(bline,aLength,"*Br%5d :%-9s : %-54s *",fgCount,GetName(),titleContent.Data());
01699 else snprintf(bline,aLength,"*Br%5d :%-9s : %-54s *",fgCount,GetName()," ");
01700 if (strlen(bline) > UInt_t(kLINEND)) {
01701 char *tmp = new char[strlen(bline)+1];
01702 if (titleLength) strlcpy(tmp, titleContent.Data(),strlen(bline)+1);
01703 snprintf(bline,aLength,"*Br%5d :%-9s : ",fgCount,GetName());
01704 int pos = strlen (bline);
01705 int npos = pos;
01706 int beg=0, end;
01707 while (beg < titleLength) {
01708 for (end=beg+1; end < titleLength-1; end ++)
01709 if (tmp[end] == ':') break;
01710 if (npos + end-beg+1 >= 78) {
01711 while (npos < kLINEND) {
01712 bline[pos ++] = ' ';
01713 npos ++;
01714 }
01715 bline[pos ++] = '*';
01716 bline[pos ++] = '\n';
01717 bline[pos ++] = '*';
01718 npos = 1;
01719 for (; npos < 12; npos ++)
01720 bline[pos ++] = ' ';
01721 bline[pos-2] = '|';
01722 }
01723 for (int n = beg; n <= end; n ++)
01724 bline[pos+n-beg] = tmp[n];
01725 pos += end-beg+1;
01726 npos += end-beg+1;
01727 beg = end+1;
01728 }
01729 while (npos < kLINEND) {
01730 bline[pos ++] = ' ';
01731 npos ++;
01732 }
01733 bline[pos ++] = '*';
01734 bline[pos] = '\0';
01735 delete[] tmp;
01736 }
01737 Printf("%s", bline);
01738 if (fTotBytes > 2000000000) {
01739 Printf("*Entries :%lld : Total Size=%11lld bytes File Size = %lld *",fEntries,totBytes,fZipBytes);
01740 } else {
01741 if (fZipBytes > 0) {
01742 Printf("*Entries :%9lld : Total Size=%11lld bytes File Size = %10lld *",fEntries,totBytes,fZipBytes);
01743 } else {
01744 if (fWriteBasket > 0) {
01745 Printf("*Entries :%9lld : Total Size=%11lld bytes All baskets in memory *",fEntries,totBytes);
01746 } else {
01747 Printf("*Entries :%9lld : Total Size=%11lld bytes One basket in memory *",fEntries,totBytes);
01748 }
01749 }
01750 }
01751 Printf("*Baskets :%9d : Basket Size=%11d bytes Compression= %6.2f *",fWriteBasket,fBasketSize,cx);
01752 Printf("*............................................................................*");
01753 delete [] bline;
01754 fgCount++;
01755 }
01756
01757
01758 void TBranch::ReadBasket(TBuffer&)
01759 {
01760
01761
01762
01763 }
01764
01765
01766 void TBranch::ReadLeavesImpl(TBuffer& b)
01767 {
01768
01769
01770 for (Int_t i = 0; i < fNleaves; ++i) {
01771 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
01772 leaf->ReadBasket(b);
01773 }
01774 }
01775
01776
01777 void TBranch::Refresh(TBranch* b)
01778 {
01779
01780
01781
01782 fEntryOffsetLen = b->fEntryOffsetLen;
01783 fWriteBasket = b->fWriteBasket;
01784 fEntryNumber = b->fEntryNumber;
01785 fMaxBaskets = b->fMaxBaskets;
01786 fEntries = b->fEntries;
01787 fTotBytes = b->fTotBytes;
01788 fZipBytes = b->fZipBytes;
01789 fReadBasket = 0;
01790 delete [] fBasketBytes;
01791 delete [] fBasketEntry;
01792 delete [] fBasketSeek;
01793 fBasketBytes = new Int_t[fMaxBaskets];
01794 fBasketEntry = new Long64_t[fMaxBaskets];
01795 fBasketSeek = new Long64_t[fMaxBaskets];
01796 Int_t i;
01797 for (i=0;i<fMaxBaskets;i++) {
01798 fBasketBytes[i] = b->fBasketBytes[i];
01799 fBasketEntry[i] = b->fBasketEntry[i];
01800 fBasketSeek[i] = b->fBasketSeek[i];
01801 }
01802 fBaskets.Delete();
01803 Int_t nbaskets = b->fBaskets.GetSize();
01804 fBaskets.Expand(nbaskets);
01805
01806
01807 TBasket *basket = (TBasket*)b->fBaskets.UncheckedAt(fWriteBasket);
01808 fBaskets.AddAt(basket,fWriteBasket);
01809 if (basket) {
01810 fNBaskets = 1;
01811 --(b->fNBaskets);
01812 b->fBaskets.RemoveAt(fWriteBasket);
01813 basket->SetBranch(this);
01814 }
01815 }
01816
01817
01818 void TBranch::Reset(Option_t*)
01819 {
01820
01821
01822
01823
01824
01825
01826 fReadBasket = 0;
01827 fReadEntry = -1;
01828 fWriteBasket = 0;
01829 fEntries = 0;
01830 fTotBytes = 0;
01831 fZipBytes = 0;
01832 fEntryNumber = 0;
01833
01834 if (fBasketBytes) {
01835 for (Int_t i = 0; i < fMaxBaskets; ++i) {
01836 fBasketBytes[i] = 0;
01837 }
01838 }
01839
01840 if (fBasketEntry) {
01841 for (Int_t i = 0; i < fMaxBaskets; ++i) {
01842 fBasketEntry[i] = 0;
01843 }
01844 }
01845
01846 if (fBasketSeek) {
01847 for (Int_t i = 0; i < fMaxBaskets; ++i) {
01848 fBasketSeek[i] = 0;
01849 }
01850 }
01851
01852 fBaskets.Delete();
01853 fNBaskets = 0;
01854 }
01855
01856
01857 void TBranch::ResetAddress()
01858 {
01859
01860
01861 fAddress = 0;
01862
01863
01864 fReadEntry = -1;
01865
01866 for (Int_t i = 0; i < fNleaves; ++i) {
01867 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
01868 leaf->SetAddress(0);
01869 }
01870
01871 Int_t nbranches = fBranches.GetEntriesFast();
01872 for (Int_t i = 0; i < nbranches; ++i) {
01873 TBranch* abranch = (TBranch*) fBranches[i];
01874
01875 abranch->ResetAddress();
01876 }
01877 }
01878
01879
01880 void TBranch::ResetCount()
01881 {
01882
01883 fgCount = 0;
01884 }
01885
01886
01887 void TBranch::SetAddress(void* addr)
01888 {
01889
01890 if (TestBit(kDoNotProcess)) {
01891 return;
01892 }
01893 fReadEntry = -1;
01894 fAddress = (char*) addr;
01895 for (Int_t i = 0; i < fNleaves; ++i) {
01896 TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
01897 Int_t offset = leaf->GetOffset();
01898 if (TestBit(kIsClone)) {
01899 offset = 0;
01900 }
01901 if (fAddress) leaf->SetAddress(fAddress + offset);
01902 else leaf->SetAddress(0);
01903 }
01904 }
01905
01906
01907 void TBranch::SetAutoDelete(Bool_t autodel)
01908 {
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922 if (autodel) {
01923 SetBit(kAutoDelete, 1);
01924 } else {
01925 SetBit(kAutoDelete, 0);
01926 }
01927 }
01928
01929
01930 void TBranch::SetBasketSize(Int_t buffsize)
01931 {
01932
01933
01934
01935 if (buffsize < 100+fEntryOffsetLen) buffsize = 100+fEntryOffsetLen;
01936 fBasketSize = buffsize;
01937 TBasket *basket = (TBasket*)fBaskets[fWriteBasket];
01938 if (basket) {
01939 basket->AdjustSize(fBasketSize);
01940 }
01941 }
01942
01943
01944 void TBranch::SetBufferAddress(TBuffer* buf)
01945 {
01946
01947
01948
01949
01950
01951
01952 if ( (fNleaves != 1)
01953 || (strcmp("TLeafObject",fLeaves.UncheckedAt(0)->ClassName())!=0) ) {
01954 Error("TBranch::SetAddress","Filling from a TBuffer can only be done with a not split object branch. Request ignored.");
01955 } else {
01956 fReadEntry = -1;
01957
01958 fEntryBuffer = buf;
01959 }
01960 }
01961
01962
01963 void TBranch::SetCompressionLevel(Int_t level)
01964 {
01965
01966
01967
01968 fCompress = level;
01969 Int_t nb = fBranches.GetEntriesFast();
01970
01971 for (Int_t i=0;i<nb;i++) {
01972 TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
01973 branch->SetCompressionLevel(level);
01974 }
01975 }
01976
01977
01978 void TBranch::SetEntryOffsetLen(Int_t newdefault, Bool_t updateExisting)
01979 {
01980
01981
01982
01983
01984 if (fEntryOffsetLen && newdefault) {
01985 fEntryOffsetLen = newdefault;
01986 }
01987 if (updateExisting) {
01988 TIter next( GetListOfBranches() );
01989 TBranch *b;
01990 while ( ( b = (TBranch*)next() ) ) {
01991 b->SetEntryOffsetLen( newdefault, kTRUE );
01992 }
01993 }
01994 }
01995
01996
01997 void TBranch::SetEntries(Long64_t entries)
01998 {
01999
02000
02001 fEntries = entries;
02002 fEntryNumber = entries;
02003 }
02004
02005
02006 void TBranch::SetFile(TFile* file)
02007 {
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026 if (file == 0) file = fTree->GetCurrentFile();
02027 fDirectory = (TDirectory*)file;
02028 if (file == fTree->GetCurrentFile()) fFileName = "";
02029 else fFileName = file->GetName();
02030
02031
02032 TIter nextb(GetListOfBaskets());
02033 TBasket *basket;
02034 while ((basket = (TBasket*)nextb())) {
02035 basket->SetParent(file);
02036 }
02037
02038
02039 TIter next(GetListOfBranches());
02040 TBranch *branch;
02041 while ((branch = (TBranch*)next())) {
02042 branch->SetFile(file);
02043 }
02044 }
02045
02046
02047 void TBranch::SetFile(const char* fname)
02048 {
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 fFileName = fname;
02068 fDirectory = 0;
02069
02070
02071 TIter next(GetListOfBranches());
02072 TBranch *branch;
02073 while ((branch = (TBranch*)next())) {
02074 branch->SetFile(fname);
02075 }
02076 }
02077
02078
02079 Bool_t TBranch::SetMakeClass(Bool_t )
02080 {
02081
02082
02083
02084
02085
02086
02087 return kFALSE;
02088 }
02089
02090
02091 void TBranch::SetObject(void * )
02092 {
02093
02094
02095 if (TestBit(kDoNotProcess)) {
02096 return;
02097 }
02098 Warning("SetObject","is not supported in TBranch objects");
02099 }
02100
02101
02102 void TBranch::SetStatus(Bool_t status)
02103 {
02104
02105
02106 if (status) ResetBit(kDoNotProcess);
02107 else SetBit(kDoNotProcess);
02108 }
02109
02110
02111 void TBranch::Streamer(TBuffer& b)
02112 {
02113
02114
02115 if (b.IsReading()) {
02116 UInt_t R__s, R__c;
02117 fTree = gTree;
02118 fAddress = 0;
02119 gROOT->SetReadingObject(kTRUE);
02120 Version_t v = b.ReadVersion(&R__s, &R__c);
02121 if (v > 9) {
02122 b.ReadClassBuffer(TBranch::Class(), this, v, R__s, R__c);
02123
02124 if (fWriteBasket>=fBaskets.GetSize()) {
02125 fBaskets.Expand(fWriteBasket+1);
02126 }
02127 fDirectory = 0;
02128 fNleaves = fLeaves.GetEntriesFast();
02129 for (Int_t i=0;i<fNleaves;i++) {
02130 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
02131 leaf->SetBranch(this);
02132 }
02133
02134 fNBaskets = fBaskets.GetEntries();
02135 for (Int_t j=fWriteBasket,n=0;j>=0 && n<fNBaskets;--j) {
02136 TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
02137 if (bk) {
02138 bk->SetBranch(this);
02139 GetTree()->IncrementTotalBuffers(bk->GetBufferSize());
02140 ++n;
02141 }
02142 }
02143 if (fWriteBasket >= fMaxBaskets) {
02144
02145 ExpandBasketArrays();
02146 fBasketBytes[fWriteBasket] = fBasketBytes[fWriteBasket-1];
02147 fBasketEntry[fWriteBasket] = fEntries;
02148 fBasketSeek [fWriteBasket] = fBasketSeek [fWriteBasket-1];
02149
02150 }
02151 if (!fSplitLevel && fBranches.GetEntriesFast()) fSplitLevel = 1;
02152 gROOT->SetReadingObject(kFALSE);
02153 return;
02154 }
02155
02156 Int_t n,i,j,ijunk;
02157 if (v > 5) {
02158 Stat_t djunk;
02159 TNamed::Streamer(b);
02160 if (v > 7) TAttFill::Streamer(b);
02161 b >> fCompress;
02162 b >> fBasketSize;
02163 b >> fEntryOffsetLen;
02164 b >> fWriteBasket;
02165 b >> ijunk; fEntryNumber = (Long64_t)ijunk;
02166 b >> fOffset;
02167 b >> fMaxBaskets;
02168 if (v > 6) b >> fSplitLevel;
02169 b >> djunk; fEntries = (Long64_t)djunk;
02170 b >> djunk; fTotBytes = (Long64_t)djunk;
02171 b >> djunk; fZipBytes = (Long64_t)djunk;
02172
02173 fBranches.Streamer(b);
02174 fLeaves.Streamer(b);
02175 fBaskets.Streamer(b);
02176 fBasketBytes = new Int_t[fMaxBaskets];
02177 fBasketEntry = new Long64_t[fMaxBaskets];
02178 fBasketSeek = new Long64_t[fMaxBaskets];
02179 Char_t isArray;
02180 b >> isArray;
02181 b.ReadFastArray(fBasketBytes,fMaxBaskets);
02182 b >> isArray;
02183 for (i=0;i<fMaxBaskets;i++) {b >> ijunk; fBasketEntry[i] = ijunk;}
02184 b >> isArray;
02185 for (i=0;i<fMaxBaskets;i++) {
02186 if (isArray == 2) b >> fBasketSeek[i];
02187 else {Int_t bsize; b >> bsize; fBasketSeek[i] = (Long64_t)bsize;};
02188 }
02189 fFileName.Streamer(b);
02190 b.CheckByteCount(R__s, R__c, TBranch::IsA());
02191 fDirectory = 0;
02192 fNleaves = fLeaves.GetEntriesFast();
02193 for (i=0;i<fNleaves;i++) {
02194 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
02195 leaf->SetBranch(this);
02196 }
02197 fNBaskets = fBaskets.GetEntries();
02198 for (j=fWriteBasket,n=0;j>0 && n<fNBaskets;--j) {
02199 TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
02200 if (bk) {
02201 bk->SetBranch(this);
02202 GetTree()->IncrementTotalBuffers(bk->GetBufferSize());
02203 ++n;
02204 }
02205 }
02206 if (fWriteBasket >= fMaxBaskets) {
02207
02208 ExpandBasketArrays();
02209 fBasketBytes[fWriteBasket] = fBasketBytes[fWriteBasket-1];
02210 fBasketEntry[fWriteBasket] = fEntries;
02211 fBasketSeek [fWriteBasket] = fBasketSeek [fWriteBasket-1];
02212
02213 }
02214
02215 if (!fSplitLevel && fBranches.GetEntriesFast()) fSplitLevel = 1;
02216 gROOT->SetReadingObject(kFALSE);
02217 b.CheckByteCount(R__s, R__c, TBranch::IsA());
02218 return;
02219 }
02220
02221 Stat_t djunk;
02222 TNamed::Streamer(b);
02223 b >> fCompress;
02224 b >> fBasketSize;
02225 b >> fEntryOffsetLen;
02226 b >> fMaxBaskets;
02227 b >> fWriteBasket;
02228 b >> ijunk; fEntryNumber = (Long64_t)ijunk;
02229 b >> djunk; fEntries = (Long64_t)djunk;
02230 b >> djunk; fTotBytes = (Long64_t)djunk;
02231 b >> djunk; fZipBytes = (Long64_t)djunk;
02232 b >> fOffset;
02233 fBranches.Streamer(b);
02234 fLeaves.Streamer(b);
02235 fNleaves = fLeaves.GetEntriesFast();
02236 for (i=0;i<fNleaves;i++) {
02237 TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
02238 leaf->SetBranch(this);
02239 }
02240 fBaskets.Streamer(b);
02241 Int_t nbaskets = fBaskets.GetEntries();
02242 for (j=fWriteBasket,n=0;j>0 && n<nbaskets;--j) {
02243 TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
02244 if (bk) {
02245 bk->SetBranch(this);
02246 GetTree()->IncrementTotalBuffers(bk->GetBufferSize());
02247 ++n;
02248 }
02249 }
02250 fBasketEntry = new Long64_t[fMaxBaskets];
02251 b >> n;
02252 for (i=0;i<n;i++) {b >> ijunk; fBasketEntry[i] = ijunk;}
02253 fBasketBytes = new Int_t[fMaxBaskets];
02254 if (v > 4) {
02255 n = b.ReadArray(fBasketBytes);
02256 } else {
02257 for (n=0;n<fMaxBaskets;n++) fBasketBytes[n] = 0;
02258 }
02259 if (v < 2) {
02260 fBasketSeek = new Long64_t[fMaxBaskets];
02261 for (n=0;n<fWriteBasket;n++) {
02262 fBasketSeek[n] = GetBasket(n)->GetSeekKey();
02263 }
02264 } else {
02265 fBasketSeek = new Long64_t[fMaxBaskets];
02266 b >> n;
02267 for (n=0;n<fMaxBaskets;n++) {
02268 Int_t aseek;
02269 b >> aseek;
02270 fBasketSeek[n] = Long64_t(aseek);
02271 }
02272 }
02273 if (v > 2) {
02274 fFileName.Streamer(b);
02275 }
02276 fDirectory = 0;
02277 if (v < 4) SetAutoDelete(kTRUE);
02278 if (!fSplitLevel && fBranches.GetEntriesFast()) fSplitLevel = 1;
02279 gROOT->SetReadingObject(kFALSE);
02280 b.CheckByteCount(R__s, R__c, TBranch::IsA());
02281
02282
02283 } else {
02284 Int_t maxBaskets = fMaxBaskets;
02285 fMaxBaskets = fWriteBasket+1;
02286 if (fMaxBaskets < 10) fMaxBaskets=10;
02287 TBasket *writebasket = 0;
02288 if (fNBaskets == 1) {
02289 writebasket = (TBasket*)fBaskets.UncheckedAt(fWriteBasket);
02290 if (writebasket && writebasket->GetNevBuf()==0) {
02291 fBaskets[fWriteBasket] = 0;
02292 } else {
02293 writebasket = 0;
02294 }
02295 }
02296 b.WriteClassBuffer(TBranch::Class(),this);
02297 if (writebasket) {
02298 fBaskets[fWriteBasket] = writebasket;
02299 }
02300 fMaxBaskets = maxBaskets;
02301 }
02302 }
02303
02304
02305 Int_t TBranch::WriteBasket(TBasket* basket, Int_t where)
02306 {
02307
02308
02309
02310 Int_t nout = basket->WriteBuffer();
02311 fBasketBytes[where] = basket->GetNbytes();
02312 fBasketSeek[where] = basket->GetSeekKey();
02313 Int_t addbytes = basket->GetObjlen() + basket->GetKeylen();
02314 TBasket *reusebasket = 0;
02315 if (nout>0) {
02316
02317 fBaskets[where] = 0;
02318
02319 reusebasket = basket;
02320 reusebasket->Reset();
02321 }
02322 fZipBytes += nout;
02323 fTotBytes += addbytes;
02324 fTree->AddTotBytes(addbytes);
02325 fTree->AddZipBytes(nout);
02326
02327 if (where==fWriteBasket) {
02328 ++fWriteBasket;
02329 if (fWriteBasket >= fMaxBaskets) {
02330 ExpandBasketArrays();
02331 }
02332 fBaskets.AddAtAndExpand(reusebasket,fWriteBasket);
02333 fBasketEntry[fWriteBasket] = fEntryNumber;
02334 } else {
02335 --fNBaskets;
02336 fBaskets[where] = 0;
02337 basket->DropBuffers();
02338 delete basket;
02339 }
02340
02341 return nout;
02342 }
02343
02344
02345 void TBranch::SetFirstEntry(Long64_t entry)
02346 {
02347
02348 fFirstEntry = entry;
02349 fEntries = 0;
02350 fEntryNumber = entry;
02351 if( fBasketEntry )
02352 fBasketEntry[0] = entry;
02353 for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i )
02354 ((TBranch*)fBranches[i])->SetFirstEntry( entry );
02355 }
02356
02357
02358 void TBranch::SetupAddresses()
02359 {
02360
02361
02362
02363
02364 }
02365
02366
02367 void TBranch::UpdateFile()
02368 {
02369
02370
02371
02372
02373 TFile *file = fTree->GetCurrentFile();
02374 if (fFileName.Length() == 0) {
02375 fDirectory = file;
02376
02377
02378 TIter nextb(GetListOfBaskets());
02379 TBasket *basket;
02380 while ((basket = (TBasket*)nextb())) {
02381 basket->SetParent(file);
02382 }
02383 }
02384
02385
02386 TIter next(GetListOfBranches());
02387 TBranch *branch;
02388 while ((branch = (TBranch*)next())) {
02389 branch->UpdateFile();
02390 }
02391 }