00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #include "TEntryList.h"
00128 #include "TEntryListBlock.h"
00129 #include "TTree.h"
00130 #include "TFile.h"
00131 #include "TSystem.h"
00132
00133 ClassImp(TEntryList)
00134
00135
00136 TEntryList::TEntryList() : fEntriesToProcess(0)
00137 {
00138
00139
00140 fLists = 0;
00141 fCurrent = 0;
00142 fBlocks = 0;
00143 fN = 0;
00144 fNBlocks = 0;
00145 fTreeName = "";
00146 fFileName = "";
00147 fStringHash = 0;
00148 fTreeNumber = -1;
00149 fDirectory = 0;
00150 fReapply = kFALSE;
00151 fLastIndexQueried = -1;
00152 fLastIndexReturned = 0;
00153 fShift = kFALSE;
00154 }
00155
00156
00157 TEntryList::TEntryList(const char *name, const char *title) :
00158 TNamed(name, title),
00159 fEntriesToProcess(0)
00160 {
00161
00162
00163 fLists = 0;
00164 fCurrent = 0;
00165 fBlocks = 0;
00166 fN = 0;
00167 fNBlocks = 0;
00168 fTreeName = "";
00169 fFileName = "";
00170 fStringHash = 0;
00171 fTreeNumber = -1;
00172 fReapply = kFALSE;
00173
00174 fDirectory = gDirectory;
00175 if (fDirectory) fDirectory->Append(this);
00176
00177 fLastIndexQueried = -1;
00178 fLastIndexReturned = 0;
00179 fShift = kFALSE;
00180 }
00181
00182
00183 TEntryList::TEntryList(const char *name, const char *title, const TTree *tree):TNamed(name, title)
00184 {
00185
00186
00187 fLists = 0;
00188 fCurrent = 0;
00189 fBlocks = 0;
00190 fN = 0;
00191 fNBlocks = 0;
00192 fTreeNumber = -1;
00193 SetTree(tree);
00194 fReapply = kFALSE;
00195
00196 fDirectory = gDirectory;
00197 if (fDirectory) fDirectory->Append(this);
00198
00199 fLastIndexQueried = -1;
00200 fLastIndexReturned = 0;
00201 fShift = kFALSE;
00202 }
00203
00204
00205 TEntryList::TEntryList(const char *name, const char *title, const char *treename, const char *filename) : TNamed(name, title),fEntriesToProcess(0)
00206 {
00207
00208
00209 fLists = 0;
00210 fCurrent = 0;
00211 fBlocks = 0;
00212 fNBlocks = 0;
00213 fN = 0;
00214 SetTree(treename, filename);
00215 fTreeNumber = -1;
00216 fReapply = kFALSE;
00217
00218 fDirectory = gDirectory;
00219 if (fDirectory) fDirectory->Append(this);
00220
00221 fLastIndexQueried = -1;
00222 fLastIndexReturned = 0;
00223 fShift = kFALSE;
00224 }
00225
00226
00227 TEntryList::TEntryList(const TTree *tree) : fEntriesToProcess(0)
00228 {
00229
00230
00231 fLists = 0;
00232 fCurrent = 0;
00233 fBlocks = 0;
00234 fNBlocks = 0;
00235 fN = 0;
00236
00237 SetTree(tree);
00238 fTreeNumber = -1;
00239
00240 fReapply = kFALSE;
00241 fDirectory = gDirectory;
00242 if (fDirectory) fDirectory->Append(this);
00243
00244 fLastIndexQueried = -1;
00245 fLastIndexReturned = 0;
00246 fShift = kFALSE;
00247 }
00248
00249
00250 TEntryList::TEntryList(const TEntryList &elist) : TNamed(elist)
00251 {
00252
00253
00254 fNBlocks = elist.fNBlocks;
00255 fTreeName = elist.fTreeName;
00256 fFileName = elist.fFileName;
00257 fStringHash = elist.fStringHash;
00258 fTreeNumber = elist.fTreeNumber;
00259 fLastIndexQueried = -1;
00260 fLastIndexReturned = 0;
00261 fN = elist.fN;
00262 fShift = elist.fShift;
00263 fLists = 0;
00264 fBlocks = 0;
00265 fReapply = elist.fReapply;
00266 fCurrent = 0;
00267 fEntriesToProcess = elist.fEntriesToProcess;
00268 if (elist.fLists){
00269 fLists = new TList();
00270 TEntryList *el1 = 0;
00271 TEntryList *el2 = 0;
00272 TIter next(elist.fLists);
00273 while((el1 = (TEntryList*)next())){
00274 el2 = new TEntryList(*el1);
00275 if (el1==elist.fCurrent)
00276 fCurrent = el2;
00277 fLists->Add(el2);
00278 }
00279 } else {
00280 if (elist.fBlocks){
00281 TEntryListBlock *block1 = 0;
00282 TEntryListBlock *block2 = 0;
00283
00284 fBlocks = new TObjArray();
00285 for (Int_t i=0; i<fNBlocks; i++){
00286 block1 = (TEntryListBlock*)elist.fBlocks->UncheckedAt(i);
00287 block2 = new TEntryListBlock(*block1);
00288 fBlocks->Add(block2);
00289 }
00290 }
00291 fCurrent = this;
00292 }
00293 fDirectory = 0;
00294
00295 }
00296
00297
00298
00299 TEntryList::~TEntryList()
00300 {
00301
00302
00303 if (fBlocks){
00304 fBlocks->Delete();
00305 delete fBlocks;
00306 }
00307 fBlocks = 0;
00308 if (fLists){
00309 fLists->Delete();
00310 delete fLists;
00311 }
00312
00313 fLists = 0;
00314
00315 if (fDirectory) fDirectory->Remove(this);
00316 fDirectory = 0;
00317
00318 }
00319
00320
00321 void TEntryList::Add(const TEntryList *elist)
00322 {
00323
00324
00325 if (fN==0){
00326 if (!fLists && fTreeName=="" && fFileName==""){
00327
00328 fNBlocks = elist->fNBlocks;
00329 fTreeName = elist->fTreeName;
00330 fFileName = elist->fFileName;
00331 fStringHash = elist->fStringHash;
00332 fTreeNumber = elist->fTreeNumber;
00333 fLastIndexQueried = -1;
00334 fLastIndexReturned = 0;
00335 fN = elist->fN;
00336 if (elist->fLists){
00337 fLists = new TList();
00338 TEntryList *el1 = 0;
00339 TEntryList *el2 = 0;
00340 TIter next(elist->fLists);
00341 while((el1 = (TEntryList*)next())){
00342 el2 = new TEntryList(*el1);
00343 if (el1==elist->fCurrent)
00344 fCurrent = el2;
00345 fLists->Add(el2);
00346 }
00347 } else {
00348 if (elist->fBlocks){
00349 TEntryListBlock *block1 = 0;
00350 TEntryListBlock *block2 = 0;
00351 fBlocks = new TObjArray();
00352 for (Int_t i=0; i<fNBlocks; i++){
00353 block1 = (TEntryListBlock*)elist->fBlocks->UncheckedAt(i);
00354 block2 = new TEntryListBlock(*block1);
00355 fBlocks->Add(block2);
00356 }
00357 }
00358 fCurrent = 0;
00359 }
00360 return;
00361 }
00362 }
00363
00364 if (!fLists){
00365 if (!elist->fLists){
00366 if (!strcmp(elist->fTreeName.Data(),fTreeName.Data()) && !strcmp(elist->fFileName.Data(),fFileName.Data())){
00367
00368 if (!elist->fBlocks)
00369
00370 return;
00371 if (!fBlocks){
00372
00373 TEntryListBlock *block1 = 0;
00374 TEntryListBlock *block2 = 0;
00375 fNBlocks = elist->fNBlocks;
00376 fN = elist->fN;
00377 fBlocks = new TObjArray();
00378 for (Int_t i=0; i<fNBlocks; i++){
00379 block1 = (TEntryListBlock*)elist->fBlocks->UncheckedAt(i);
00380 block2 = new TEntryListBlock(*block1);
00381 fBlocks->Add(block2);
00382 }
00383 return;
00384 }
00385
00386 TEntryListBlock *block1=0;
00387 TEntryListBlock *block2=0;
00388 Int_t i;
00389 Int_t nmin = TMath::Min(fNBlocks, elist->fNBlocks);
00390 Long64_t nnew, nold;
00391 for (i=0; i<nmin; i++){
00392 block1 = (TEntryListBlock*)fBlocks->UncheckedAt(i);
00393 block2 = (TEntryListBlock*)elist->fBlocks->UncheckedAt(i);
00394 nold = block1->GetNPassed();
00395 nnew = block1->Merge(block2);
00396 fN = fN - nold + nnew;
00397 }
00398 if (fNBlocks<elist->fNBlocks){
00399 Int_t nmax = elist->fNBlocks;
00400 for (i=nmin; i<nmax; i++){
00401 block2 = (TEntryListBlock*)elist->fBlocks->UncheckedAt(i);
00402 block1 = new TEntryListBlock(*block2);
00403 fBlocks->Add(block1);
00404 fN+=block1->GetNPassed();
00405 fNBlocks++;
00406 }
00407 }
00408 fLastIndexQueried = -1;
00409 fLastIndexReturned = 0;
00410 } else {
00411
00412
00413 fLastIndexQueried = -1;
00414 fLastIndexReturned = 0;
00415 fLists = new TList();
00416 TEntryList *el = new TEntryList();
00417 el->fTreeName = fTreeName;
00418 el->fFileName = fFileName;
00419 el->fBlocks = fBlocks;
00420 fBlocks = 0;
00421 el->fNBlocks = fNBlocks;
00422 el->fN = fN;
00423 el->fLastIndexQueried = -1;
00424 el->fLastIndexReturned = 0;
00425 fLists->Add(el);
00426 el = new TEntryList(*elist);
00427 el->fLastIndexQueried = -1;
00428 el->fLastIndexReturned = 0;
00429 fLists->Add(el);
00430 fN+=el->GetN();
00431 fCurrent = 0;
00432 }
00433 } else {
00434
00435 TEntryList *el = 0;
00436 TIter next(elist->fLists);
00437 while ((el = (TEntryList*)next())){
00438 Add(el);
00439 }
00440 fCurrent = 0;
00441 }
00442 } else {
00443
00444 if (!elist->fLists){
00445
00446 TIter next(fLists);
00447 TEntryList *el = 0;
00448 Bool_t found = kFALSE;
00449 while ((el = (TEntryList*)next())){
00450 if (!strcmp(el->fTreeName.Data(), elist->fTreeName.Data()) &&
00451 !strcmp(el->fFileName.Data(), elist->fFileName.Data())){
00452
00453
00454 Long64_t oldn = el->GetN();
00455 el->Add(elist);
00456 found = kTRUE;
00457 fN = fN - oldn + el->GetN();
00458 break;
00459 }
00460 }
00461 if (!found){
00462 el = new TEntryList(*elist);
00463 el->fLastIndexQueried = -1;
00464 el->fLastIndexReturned = 0;
00465 fLists->Add(el);
00466 fN+=el->GetN();
00467 }
00468 } else {
00469
00470 TEntryList *el = 0;
00471 TIter next(elist->fLists);
00472 while ((el = (TEntryList*)next())){
00473 Add(el);
00474 }
00475 fCurrent = 0;
00476 }
00477 if (fCurrent){
00478 if (fCurrent->fBlocks){
00479 Int_t currentblock = (fCurrent->fLastIndexReturned)/kBlockSize;
00480 TEntryListBlock *block = (TEntryListBlock*)fCurrent->fBlocks->UncheckedAt(currentblock);
00481 block->ResetIndices();
00482 fCurrent->fLastIndexReturned = 0;
00483 fCurrent->fLastIndexQueried = -1;
00484 }
00485 }
00486 fCurrent = 0;
00487 }
00488
00489 }
00490
00491
00492
00493 Int_t TEntryList::Contains(Long64_t entry, TTree *tree)
00494 {
00495
00496
00497
00498
00499
00500 if (!tree){
00501 if (fBlocks) {
00502
00503 TEntryListBlock *block = 0;
00504 Int_t nblock = entry/kBlockSize;
00505 if (nblock >= fNBlocks) return 0;
00506 block = (TEntryListBlock*)fBlocks->UncheckedAt(nblock);
00507 return block->Contains(entry-nblock*kBlockSize);
00508 }
00509 if (fLists) {
00510 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
00511 return fCurrent->Contains(entry);
00512 }
00513 return 0;
00514 } else {
00515 Long64_t localEntry = tree->LoadTree(entry);
00516 SetTree(tree->GetTree());
00517 if (fCurrent)
00518 return fCurrent->Contains(localEntry);
00519 }
00520 return 0;
00521
00522 }
00523
00524
00525 void TEntryList::DirectoryAutoAdd(TDirectory* dir)
00526 {
00527
00528
00529 SetDirectory(dir);
00530 }
00531
00532
00533 Bool_t TEntryList::Enter(Long64_t entry, TTree *tree)
00534 {
00535
00536
00537
00538
00539
00540
00541 if (!tree){
00542 if (!fLists) {
00543 if (!fBlocks) fBlocks = new TObjArray();
00544 TEntryListBlock *block = 0;
00545 Long64_t nblock = entry/kBlockSize;
00546 if (nblock >= fNBlocks) {
00547 if (fNBlocks>0){
00548 block = (TEntryListBlock*)fBlocks->UncheckedAt(fNBlocks-1);
00549 if (!block) return 0;
00550 block->OptimizeStorage();
00551 }
00552 for (Int_t i=fNBlocks; i<=nblock; i++){
00553 block = new TEntryListBlock();
00554 fBlocks->Add(block);
00555 }
00556 fNBlocks = nblock+1;
00557 }
00558 block = (TEntryListBlock*)fBlocks->UncheckedAt(nblock);
00559 if (block->Enter(entry-nblock*kBlockSize)) {
00560 fN++;
00561 return 1;
00562 }
00563 } else {
00564
00565 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
00566 if (fCurrent->Enter(entry)) {
00567 if (fLists)
00568 fN++;
00569 return 1;
00570 }
00571 }
00572 } else {
00573 Long64_t localentry = tree->LoadTree(entry);
00574 SetTree(tree->GetTree());
00575 if (fCurrent){
00576 if (fCurrent->Enter(localentry)) {
00577 if (fLists)
00578 fN++;
00579 return 1;
00580 }
00581 }
00582 }
00583 return 0;
00584
00585 }
00586
00587
00588 Bool_t TEntryList::Remove(Long64_t entry, TTree *tree)
00589 {
00590
00591
00592
00593
00594
00595
00596 if (!tree){
00597 if (!fLists) {
00598 if (!fBlocks) return 0;
00599 TEntryListBlock *block = 0;
00600 Long64_t nblock = entry/kBlockSize;
00601 block = (TEntryListBlock*)fBlocks->UncheckedAt(nblock);
00602 if (!block) return 0;
00603 Long64_t blockindex = entry - nblock*kBlockSize;
00604 if (block->Remove(blockindex)){
00605 fN--;
00606 return 1;
00607 }
00608 } else {
00609 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
00610 if (fCurrent->Remove(entry)){
00611 if (fLists)
00612 fN--;
00613 return 1;
00614 }
00615 }
00616 } else {
00617 Int_t localentry = tree->LoadTree(entry);
00618 SetTree(tree->GetTree());
00619 if (fCurrent){
00620 if (fCurrent->Remove(localentry)) {
00621 if (fLists)
00622 fN--;
00623 return 1;
00624 }
00625 }
00626 }
00627 return 0;
00628 }
00629
00630
00631 Long64_t TEntryList::GetEntry(Int_t index)
00632 {
00633
00634
00635
00636
00637 if (index>=fN){
00638 return -1;
00639 }
00640 if (index==fLastIndexQueried+1){
00641
00642 return Next();
00643 } else {
00644 if (fBlocks) {
00645 TEntryListBlock *block = 0;
00646 Long64_t total_passed = 0;
00647 Int_t i=0;
00648 while (total_passed<=index && i<fNBlocks){
00649 block=(TEntryListBlock*)fBlocks->UncheckedAt(i);
00650 total_passed+=block->GetNPassed();
00651 i++;
00652 }
00653 i--;
00654 total_passed-=block->GetNPassed();
00655 if (i!=fLastIndexReturned/kBlockSize){
00656 block = (TEntryListBlock*)fBlocks->UncheckedAt(fLastIndexReturned/kBlockSize);
00657 block->ResetIndices();
00658 block = (TEntryListBlock*)fBlocks->UncheckedAt(i);
00659 }
00660
00661 Long64_t localindex = index - total_passed;
00662 Long64_t blockindex = block->GetEntry(localindex);
00663 if (blockindex < 0) return -1;
00664 Long64_t res = i*kBlockSize + blockindex;
00665 fLastIndexQueried = index;
00666 fLastIndexReturned = res;
00667 return res;
00668 } else {
00669
00670 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
00671 TIter next(fLists);
00672 TEntryList *templist;
00673 Long64_t ntotal = 0;
00674 if (fCurrent){
00675
00676 if (fCurrent->fBlocks){
00677 Int_t currentblock = (fCurrent->fLastIndexReturned)/kBlockSize;
00678 TEntryListBlock *block = (TEntryListBlock*)fCurrent->fBlocks->UncheckedAt(currentblock);
00679 block->ResetIndices();
00680 fCurrent->fLastIndexReturned = 0;
00681 fCurrent->fLastIndexQueried = -1;
00682 }
00683 }
00684 while ((templist = (TEntryList*)next())){
00685 if (!fShift){
00686 ntotal += templist->GetN();
00687 } else {
00688 if (templist->GetTreeNumber() >= 0)
00689 ntotal += templist->GetN();
00690 }
00691 if (ntotal > index)
00692 break;
00693 }
00694 fCurrent = templist;
00695 if (!fCurrent) return -1;
00696 Long64_t localentry = index - (ntotal - fCurrent->GetN());
00697 fLastIndexQueried = index;
00698 fLastIndexReturned = fCurrent->GetEntry(localentry);
00699 return fLastIndexReturned;
00700 }
00701
00702 }
00703 return -1;
00704 }
00705
00706
00707 Long64_t TEntryList::GetEntryAndTree(Int_t index, Int_t &treenum)
00708 {
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 Long64_t result = GetEntry(index);
00722 if (fLists)
00723 treenum = fCurrent->fTreeNumber;
00724 else
00725 treenum = fTreeNumber;
00726 if (treenum<0) return -1;
00727
00728 return result;
00729 }
00730
00731
00732 TEntryList *TEntryList::GetEntryList(const char *treename, const char *filename, Option_t *opt)
00733 {
00734
00735
00736
00737
00738
00739 if (gDebug > 1)
00740 Info("GetEntryList","tree: %s, file: %s",
00741 (treename ? treename : "-"), (filename ? filename : "-"));
00742
00743 if (!treename || !filename) return 0;
00744 TString option = opt;
00745 option.ToUpper();
00746 Bool_t nexp = option.Contains("NE");
00747
00748 TString fn;
00749 TUrl u(filename, kTRUE);
00750
00751 Bool_t local=kFALSE;
00752 if (!nexp){
00753 local = !strcmp(u.GetProtocol(), "file");
00754 if (local) fn = u.GetFile();
00755 else fn = u.GetUrl();
00756 } else {
00757 fn = filename;
00758 }
00759
00760 if (!fLists){
00761
00762 if (!strcmp(treename, fTreeName.Data()) && !(strcmp(fn.Data(), fFileName.Data()))){
00763 return this;
00764 } else {
00765
00766 if (!nexp && local){
00767 gSystem->ExpandPathName(fn);
00768 if (!gSystem->IsAbsoluteFileName(fn))
00769 gSystem->PrependPathName(gSystem->pwd(), fn);
00770 fn = gSystem->UnixPathName(fn);
00771 if (!strcmp(treename, fTreeName.Data()) && !(strcmp(fn.Data(), fFileName.Data())))
00772 return this;
00773 }
00774 return 0;
00775 }
00776 }
00777
00778 TString stotal = treename;
00779 stotal.Append(fn);
00780 ULong_t newhash = stotal.Hash();
00781
00782 TIter next(fLists);
00783 TEntryList *templist;
00784 while ((templist = (TEntryList*)next())){
00785 if (templist->fStringHash==0){
00786 stotal = templist->fTreeName + templist->fFileName;
00787 templist->fStringHash = stotal.Hash();
00788 }
00789 if (newhash == templist->fStringHash){
00790 if (!strcmp(templist->GetTreeName(), treename) && !strcmp(templist->GetFileName(), fn.Data())){
00791 return templist;
00792 }
00793 }
00794 }
00795
00796
00797 if (!nexp && local){
00798 TString longname = fn;
00799 gSystem->ExpandPathName(longname);
00800 if (!gSystem->IsAbsoluteFileName(longname))
00801 gSystem->PrependPathName(gSystem->pwd(), longname);
00802 longname = gSystem->UnixPathName(longname);
00803 stotal = treename;
00804 stotal.Append(longname);
00805 newhash = stotal.Hash();
00806 next.Reset();
00807 while ((templist = (TEntryList*)next())){
00808 if (templist->fStringHash==0){
00809 stotal = templist->fTreeName + templist->fFileName;
00810 templist->fStringHash = stotal.Hash();
00811 }
00812 if (newhash == templist->fStringHash){
00813 if (!strcmp(templist->GetTreeName(), treename) && !strcmp(templist->GetFileName(), longname)){
00814 return templist;
00815 }
00816 }
00817 }
00818 }
00819 return 0;
00820 }
00821
00822
00823 Int_t TEntryList::Merge(TCollection *list)
00824 {
00825
00826
00827 if (!list) return -1;
00828 TIter next(list);
00829 TEntryList *elist = 0;
00830 while ((elist = (TEntryList*)next())) {
00831 if (!elist->InheritsFrom(TEntryList::Class())) {
00832 Error("Add","Attempt to add object of class: %s to a %s",elist->ClassName(),this->ClassName());
00833 return -1;
00834 }
00835 Add(elist);
00836 }
00837 return 0;
00838 }
00839
00840
00841 Long64_t TEntryList::Next()
00842 {
00843
00844
00845
00846 Long64_t result;
00847 if (fN == fLastIndexQueried+1 || fN==0){
00848 return -1;
00849 }
00850 if (fBlocks){
00851 Int_t iblock = fLastIndexReturned/kBlockSize;
00852 TEntryListBlock *current_block = (TEntryListBlock*)fBlocks->UncheckedAt(iblock);
00853 result = current_block->Next();
00854 if (result>=0) {
00855 fLastIndexQueried++;
00856 fLastIndexReturned = result+kBlockSize*iblock;
00857 return fLastIndexReturned;
00858 }
00859 else {
00860 while (result<0 && iblock<fNBlocks-1) {
00861 current_block->ResetIndices();
00862 iblock++;
00863 current_block = (TEntryListBlock*)fBlocks->UncheckedAt(iblock);
00864 current_block->ResetIndices();
00865 result = current_block->Next();
00866 }
00867 if (result<0) {
00868 fLastIndexQueried = -1;
00869 fLastIndexReturned = 0;
00870 return -1;
00871 }
00872 fLastIndexQueried++;
00873 fLastIndexReturned = result+kBlockSize*iblock;
00874
00875 return fLastIndexReturned;
00876 }
00877 } else {
00878 if (!fCurrent) {
00879 fCurrent = (TEntryList*)fLists->First();
00880 if (!fCurrent) return 0;
00881 if (fShift) {
00882 while (fCurrent->GetTreeNumber()<0) {
00883 fCurrent = (TEntryList*)fLists->After(fCurrent);
00884 if (!fCurrent) return 0;
00885 }
00886 }
00887 }
00888 result = fCurrent->Next();
00889 if (result>=0) {
00890 fLastIndexQueried++;
00891 fLastIndexReturned = result;
00892 return result;
00893 } else {
00894 if (fCurrent){
00895
00896 if (fCurrent->fBlocks){
00897 Int_t currentblock = (fCurrent->fLastIndexReturned)/kBlockSize;
00898 TEntryListBlock *block = (TEntryListBlock*)fCurrent->fBlocks->UncheckedAt(currentblock);
00899 block->ResetIndices();
00900 fCurrent->fLastIndexReturned = 0;
00901 fCurrent->fLastIndexQueried = -1;
00902 }
00903 }
00904
00905
00906 while (result<0 && fCurrent!=((TEntryList*)fLists->Last())){
00907 if (!fCurrent) return 0;
00908 fCurrent->fLastIndexQueried = -1;
00909 fCurrent->fLastIndexReturned = 0;
00910 fCurrent = (TEntryList*)fLists->After(fCurrent);
00911
00912
00913 if (!fCurrent) return 0;
00914 if (!fShift)
00915 result = fCurrent->Next();
00916 else {
00917 if (fCurrent->GetTreeNumber() >= 0)
00918 result = fCurrent->Next();
00919 }
00920 }
00921 fLastIndexQueried++;
00922 fLastIndexReturned = result;
00923 return result;
00924 }
00925 }
00926 }
00927
00928
00929
00930 void TEntryList::OptimizeStorage()
00931 {
00932
00933
00934 if (fBlocks){
00935 TEntryListBlock *block = 0;
00936 for (Int_t i=0; i<fNBlocks; i++){
00937 block = (TEntryListBlock*)fBlocks->UncheckedAt(i);
00938 block->OptimizeStorage();
00939 }
00940 }
00941 }
00942
00943
00944
00945 void TEntryList::Print(const Option_t* option) const
00946 {
00947
00948
00949
00950
00951 TString opt = option;
00952 opt.ToUpper();
00953 if (fBlocks) {
00954 printf("%s %s\n", fTreeName.Data(), fFileName.Data());
00955 if (opt.Contains("A")){
00956 TEntryListBlock* block = 0;
00957 for (Int_t i=0; i<fNBlocks; i++){
00958 block = (TEntryListBlock*)fBlocks->UncheckedAt(i);
00959 Int_t shift = i*kBlockSize;
00960 block->PrintWithShift(shift);
00961 }
00962 }
00963 }
00964 else {
00965 TEntryList *elist = 0;
00966 if (fN>0){
00967 TIter next(fLists);
00968 while((elist = (TEntryList*)next())){
00969 elist->Print(option);
00970 }
00971 } else {
00972 if (!fLists) printf("%s %s\n", fTreeName.Data(), fFileName.Data());
00973 else {
00974 TIter next(fLists);
00975 while ((elist = (TEntryList*)next())){
00976 printf("%s %s\n", elist->GetTreeName(), elist->GetFileName());
00977 }
00978 }
00979 }
00980 }
00981 }
00982
00983
00984 void TEntryList::Reset()
00985 {
00986
00987
00988
00989
00990 if (fBlocks){
00991 fBlocks->Delete();
00992 delete fBlocks;
00993 fBlocks = 0;
00994 }
00995 if (fLists){
00996 if (!((TEntryList*)fLists->First())->GetDirectory()){
00997 fLists->Delete();
00998 }
00999 delete fLists;
01000 fLists = 0;
01001 }
01002 fCurrent = 0;
01003 fBlocks = 0;
01004 fNBlocks = 0;
01005 fN = 0;
01006 fTreeName = "";
01007 fFileName = "";
01008 fStringHash = 0;
01009 fTreeNumber = -1;
01010 fLastIndexQueried = -1;
01011 fLastIndexReturned = 0;
01012 fReapply = kFALSE;
01013 }
01014
01015
01016 void TEntryList::SetDirectory(TDirectory *dir)
01017 {
01018
01019
01020 if (fDirectory == dir) return;
01021 if (fDirectory) fDirectory->Remove(this);
01022 fDirectory = dir;
01023 if (fDirectory) fDirectory->Append(this);
01024 }
01025
01026
01027 void TEntryList::SetTree(const char *treename, const char *filename)
01028 {
01029
01030
01031
01032
01033
01034 TEntryList *elist = 0;
01035
01036 TString stotal = treename;
01037 stotal.Append(filename);
01038
01039 ULong_t newhash = stotal.Hash();
01040 if (fLists) {
01041
01042 if (!fCurrent) fCurrent = (TEntryList*)fLists->First();
01043 if (fCurrent->fStringHash == 0){
01044 stotal = fCurrent->fTreeName + fCurrent->fFileName;
01045 fCurrent->fStringHash = stotal.Hash();
01046 }
01047 if (newhash == fCurrent->fStringHash){
01048
01049 if (!strcmp(fCurrent->fTreeName, treename) && !strcmp(fCurrent->fFileName, filename)){
01050 return;
01051 }
01052 }
01053 TIter next(fLists);
01054 while ((elist = (TEntryList*)next())){
01055 if (newhash == elist->fStringHash){
01056 if (!strcmp(elist->GetTreeName(), treename) && !strcmp(elist->GetFileName(), filename)){
01057
01058
01059
01060 if (fCurrent->fBlocks){
01061 Int_t currentblock = (fCurrent->fLastIndexReturned)/kBlockSize;
01062 TEntryListBlock *block = (TEntryListBlock*)fCurrent->fBlocks->UncheckedAt(currentblock);
01063 block->ResetIndices();
01064 fCurrent->fLastIndexReturned = 0;
01065 fCurrent->fLastIndexQueried = -1;
01066 }
01067 fCurrent = elist;
01068 fLastIndexQueried = -3;
01069 return;
01070 }
01071 }
01072 }
01073
01074 elist = new TEntryList("", "", treename, filename);
01075 if (elist->GetDirectory()) {
01076
01077 elist->GetDirectory()->Remove(elist);
01078 elist->SetDirectory(0);
01079 }
01080 fLists->Add(elist);
01081 fCurrent = elist;
01082 return;
01083 } else {
01084 if (fN==0 && fTreeName=="" && fFileName==""){
01085
01086 fTreeName = treename;
01087 fFileName = filename;
01088 stotal = fTreeName + fFileName;
01089
01090 fStringHash = newhash;
01091 fCurrent = this;
01092 } else {
01093 if (fStringHash == 0){
01094 stotal = fTreeName + fFileName;
01095 fStringHash = stotal.Hash();
01096 }
01097 if (newhash != fStringHash){
01098
01099
01100 fLists = new TList();
01101 elist = new TEntryList();
01102 elist->fTreeName = fTreeName;
01103 elist->fFileName = fFileName;
01104 elist->fStringHash = fStringHash;
01105 elist->fN = fN;
01106 elist->fTreeNumber = fTreeNumber;
01107 elist->fBlocks = fBlocks;
01108 fBlocks = 0;
01109 elist->fNBlocks = fNBlocks;
01110 fLists->Add(elist);
01111 elist = new TEntryList("", "", treename, filename);
01112 if (elist->GetDirectory()) {
01113
01114 elist->GetDirectory()->Remove(elist);
01115 elist->SetDirectory(0);
01116 }
01117 fLists->Add(elist);
01118 fCurrent = elist;
01119
01120
01121 fLastIndexQueried = -3;
01122
01123 }
01124 else {
01125
01126 return;
01127 }
01128 }
01129 }
01130 }
01131
01132
01133 void TEntryList::SetTree(const TTree *tree)
01134 {
01135
01136
01137
01138
01139
01140
01141
01142
01143 if (!tree) return;
01144 TString treename = tree->GetTree()->GetName();
01145 TString filename;
01146 if (tree->GetTree()->GetCurrentFile()){
01147 filename = tree->GetTree()->GetCurrentFile()->GetName();
01148 TUrl url(filename.Data(), kTRUE);
01149 if (!strcmp(url.GetProtocol(), "file")){
01150 gSystem->ExpandPathName(filename);
01151 if (!gSystem->IsAbsoluteFileName(filename))
01152 gSystem->PrependPathName(gSystem->pwd(), filename);
01153 filename = gSystem->UnixPathName(filename);
01154 } else {
01155 filename = url.GetUrl();
01156 }
01157 } else {
01158
01159 filename = "";
01160 }
01161 SetTree(treename, filename);
01162
01163 }
01164
01165
01166 void TEntryList::Subtract(const TEntryList *elist)
01167 {
01168
01169
01170 TEntryList *templist = 0;
01171 if (!fLists){
01172 if (!fBlocks) return;
01173
01174 if (!elist->fLists){
01175
01176 if (!strcmp(elist->fTreeName.Data(),fTreeName.Data()) &&
01177 !strcmp(elist->fFileName.Data(),fFileName.Data())){
01178
01179 Long64_t n2 = elist->GetN();
01180 Long64_t entry;
01181 for (Int_t i=0; i<n2; i++){
01182 entry = (const_cast<TEntryList*>(elist))->GetEntry(i);
01183 Remove(entry);
01184 }
01185 } else {
01186
01187 return;
01188 }
01189 } else {
01190
01191 TIter next1(elist->GetLists());
01192 templist = 0;
01193 Bool_t found = kFALSE;
01194 while ((templist = (TEntryList*)next1())){
01195 if (!strcmp(templist->fTreeName.Data(),fTreeName.Data()) &&
01196 !strcmp(templist->fFileName.Data(),fFileName.Data())){
01197 found = kTRUE;
01198 break;
01199 }
01200 }
01201 if (found) {
01202 Subtract(templist);
01203 }
01204 }
01205 } else {
01206
01207 TIter next2(fLists);
01208 templist = 0;
01209 Long64_t oldn=0;
01210 while ((templist = (TEntryList*)next2())){
01211 oldn = templist->GetN();
01212 templist->Subtract(elist);
01213 fN = fN - oldn + templist->GetN();
01214 }
01215 }
01216 return;
01217
01218
01219 }
01220
01221
01222 TEntryList operator||(TEntryList &elist1, TEntryList &elist2)
01223 {
01224 TEntryList eresult = elist1;
01225
01226
01227 eresult.Print("all");
01228 eresult.Add(&elist2);
01229
01230 eresult.Print("all");
01231
01232 return eresult;
01233 }
01234
01235