TEventIter.cxx

Go to the documentation of this file.
00001 // @(#)root/proofplayer:$Id: TEventIter.cxx 37396 2010-12-08 13:12:00Z rdm $
00002 // Author: Maarten Ballintijn   07/01/02
00003 // Modified: Long Tran-Thanh    04/09/07  (Addition of TEventIterUnit)
00004 
00005 /*************************************************************************
00006  * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers.               *
00007  * All rights reserved.                                                  *
00008  *                                                                       *
00009  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00010  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00011  *************************************************************************/
00012 
00013 //////////////////////////////////////////////////////////////////////////
00014 //                                                                      //
00015 // TEventIter                                                           //
00016 //                                                                      //
00017 // Special iterator class used in TProofPlayer to iterate over events   //
00018 // or objects in the packets.                                           //
00019 //                                                                      //
00020 //////////////////////////////////////////////////////////////////////////
00021 
00022 #include "TEnv.h"
00023 #include "TEventIter.h"
00024 #include "TFriendElement.h"
00025 #include "TCollection.h"
00026 #include "TDSet.h"
00027 #include "TFile.h"
00028 #include "TKey.h"
00029 #include "TProofDebug.h"
00030 #include "TSelector.h"
00031 #include "TTimeStamp.h"
00032 #include "TTree.h"
00033 #include "TTreeCache.h"
00034 #include "TTreeCacheUnzip.h"
00035 #include "TVirtualPerfStats.h"
00036 #include "TEventList.h"
00037 #include "TEntryList.h"
00038 #include "TList.h"
00039 #include "TMap.h"
00040 #include "TObjString.h"
00041 #include "TRegexp.h"
00042 #include "TProofServ.h"
00043 
00044 #include "TError.h"
00045 
00046 
00047 ClassImp(TEventIter)
00048 
00049 //______________________________________________________________________________
00050 TEventIter::TEventIter()
00051 {
00052    // Default constructor
00053 
00054    fDSet  = 0;
00055    fElem  = 0;
00056    fFile  = 0;
00057    fDir   = 0;
00058    fSel   = 0;
00059    fFirst = 0;
00060    fCur   = -1;
00061    fNum   = 0;
00062    fStop  = kFALSE;
00063    fOldBytesRead = 0;
00064    fEventList = 0;
00065    fEventListPos = 0;
00066    fEntryList = 0;
00067    fEntryListPos = 0;
00068    fElemFirst = 0;
00069    fElemNum = 0;
00070    fElemCur = -1;
00071 }
00072 
00073 //______________________________________________________________________________
00074 TEventIter::TEventIter(TDSet *dset, TSelector *sel, Long64_t first, Long64_t num)
00075    : fDSet(dset), fSel(sel)
00076 {
00077    // Constructor
00078 
00079    fElem  = 0;
00080    fFile  = 0;
00081    fDir   = 0;
00082    fFirst = first;
00083    fCur   = -1;
00084    fNum   = num;
00085    fStop  = kFALSE;
00086    fEventList = 0;
00087    fEventListPos = 0;
00088    fEntryList = 0;
00089    fEntryListPos = 0;
00090    fOldBytesRead = 0;
00091    fElemFirst = 0;
00092    fElemNum = 0;
00093    fElemCur = -1;
00094 }
00095 
00096 //______________________________________________________________________________
00097 TEventIter::~TEventIter()
00098 {
00099    // Destructor
00100 
00101    delete fFile;
00102 }
00103 
00104 //______________________________________________________________________________
00105 void TEventIter::StopProcess(Bool_t /*abort*/)
00106 {
00107    // Set flag to stop the process
00108 
00109    fStop = kTRUE;
00110 }
00111 
00112 //______________________________________________________________________________
00113 TEventIter *TEventIter::Create(TDSet *dset, TSelector *sel, Long64_t first, Long64_t num)
00114 {
00115    // Create and instance of the appropriate iterator
00116 
00117    if (dset->TestBit(TDSet::kEmpty)) {
00118       return new TEventIterUnit(dset, sel, num);
00119    }  else if (dset->IsTree()) {
00120       return new TEventIterTree(dset, sel, first, num);
00121    } else {
00122       return new TEventIterObj(dset, sel, first, num);
00123    }
00124 }
00125 
00126 //______________________________________________________________________________
00127 Int_t TEventIter::LoadDir()
00128 {
00129    // Load directory
00130 
00131    Int_t ret = 0;
00132 
00133    // Check Filename
00134    if ( fFile == 0 || fFilename != fElem->GetFileName() ) {
00135       fDir = 0;
00136       delete fFile; fFile = 0;
00137 
00138       fFilename = fElem->GetFileName();
00139 
00140       TDirectory *dirsave = gDirectory;
00141 
00142       Double_t start = 0;
00143       if (gPerfStats) start = TTimeStamp();
00144 
00145       // Take into acoount possible prefixes
00146       TFile::EFileType typ = TFile::kDefault;
00147       TString fname = gEnv->GetValue("Path.Localroot","");
00148       if (!fname.IsNull())
00149          typ = TFile::GetType(fFilename, "", &fname);
00150       if (typ != TFile::kLocal)
00151          fname = fFilename;
00152       fFile = TFile::Open(fname);
00153 
00154       if (gPerfStats) {
00155          gPerfStats->FileOpenEvent(fFile, fFilename, start);
00156          fOldBytesRead = 0;
00157       }
00158 
00159       if (dirsave) dirsave->cd();
00160 
00161       if (!fFile || fFile->IsZombie() ) {
00162          if (fFile)
00163             Error("Process","Cannot open file: %s (%s)",
00164                fFilename.Data(), strerror(fFile->GetErrno()) );
00165          else
00166             Error("Process","Cannot open file: %s (errno unavailable)",
00167                fFilename.Data());
00168          // cleanup ?
00169          return -1;
00170       }
00171       PDB(kLoop,2) Info("LoadDir","Opening file: %s", fFilename.Data() );
00172       ret = 1;
00173    }
00174 
00175    // Check Directory
00176    if ( fDir == 0 || fPath != fElem->GetDirectory() ) {
00177       TDirectory *dirsave = gDirectory;
00178 
00179       fPath = fElem->GetDirectory();
00180       if ( !fFile->cd(fPath) ) {
00181          Error("Process","Cannot cd to: %s",
00182             fPath.Data() );
00183          return -1;
00184       }
00185       PDB(kLoop,2) Info("Process","Cd to: %s", fPath.Data() );
00186       fDir = gDirectory;
00187       if (dirsave) dirsave->cd();
00188       ret = 1;
00189    }
00190 
00191    return ret;
00192 }
00193 
00194 //------------------------------------------------------------------------
00195 
00196 
00197 ClassImp(TEventIterUnit)
00198 
00199 //______________________________________________________________________________
00200 TEventIterUnit::TEventIterUnit()
00201 {
00202    // Default constructor
00203 
00204    fDSet = 0;
00205    fElem = 0;
00206    fSel = 0;
00207    fNum = 0;
00208    fCurrent = 0;
00209    fStop = kFALSE;
00210    fOldBytesRead = 0; // Measures the bytes written
00211 }
00212 
00213 //______________________________________________________________________________
00214 TEventIterUnit::TEventIterUnit(TDSet* dset, TSelector *sel, Long64_t num)
00215 {
00216    // Main constructor
00217 
00218    fDSet = dset;
00219    fElem = 0;
00220    fSel = sel;
00221    fNum = num;
00222    fCurrent = 0;
00223    fStop = kFALSE;
00224    fOldBytesRead = 0; // Measures the bytes written
00225 }
00226 
00227 //______________________________________________________________________________
00228 Long64_t TEventIterUnit::GetNextEvent()
00229 {
00230    // Get next event
00231 
00232    if (fStop || fNum == 0)
00233       return -1;
00234 
00235    if (fElem) fElem->ResetBit(TDSetElement::kNewPacket);
00236 
00237    while (fElem == 0 || fCurrent == 0) {
00238 
00239       if (gPerfStats) {
00240          Long64_t totBytesWritten = TFile::GetFileBytesWritten();
00241          Long64_t bytesWritten = totBytesWritten - fOldBytesRead;
00242          PDB(kLoop, 2) Info("GetNextEvent", "bytes written: %lld", bytesWritten);
00243          gPerfStats->SetBytesRead(bytesWritten);
00244          fOldBytesRead = totBytesWritten;
00245       }
00246 
00247       SafeDelete(fElem);
00248       if (!(fElem = fDSet->Next()))
00249          return -1;
00250       fElem->SetBit(TDSetElement::kNewPacket);
00251 
00252       if (!fElem->TestBit(TDSetElement::kEmpty)) {
00253          Error("GetNextEvent", "data element must be set to kEmtpy");
00254          return -1;
00255       }
00256 
00257       fNum = fElem->GetNum();
00258       if (!(fCurrent = fNum)) {
00259          fNum = 0;
00260          return -1;
00261       }
00262       fFirst = fElem->GetFirst();
00263    }
00264    Long64_t event = fNum - fCurrent + fFirst ;
00265    --fCurrent;
00266    return event;
00267 }
00268 
00269 //------------------------------------------------------------------------
00270 
00271 
00272 ClassImp(TEventIterObj)
00273 
00274 //______________________________________________________________________________
00275 TEventIterObj::TEventIterObj()
00276 {
00277    // Default ctor.
00278 
00279    fKeys     = 0;
00280    fNextKey  = 0;
00281    fObj      = 0;
00282 }
00283 
00284 //______________________________________________________________________________
00285 TEventIterObj::TEventIterObj(TDSet *dset, TSelector *sel, Long64_t first, Long64_t num)
00286    : TEventIter(dset,sel,first,num)
00287 {
00288    // Constructor
00289 
00290    fClassName = dset->GetType();
00291    fKeys     = 0;
00292    fNextKey  = 0;
00293    fObj      = 0;
00294 }
00295 
00296 
00297 //______________________________________________________________________________
00298 TEventIterObj::~TEventIterObj()
00299 {
00300    // Destructor
00301 
00302    // delete fKeys ?
00303    delete fNextKey;
00304    delete fObj;
00305 }
00306 
00307 //______________________________________________________________________________
00308 Long64_t TEventIterObj::GetNextEvent()
00309 {
00310    // Get next event
00311 
00312    if (fStop || fNum == 0) return -1;
00313 
00314    if (fElem) fElem->ResetBit(TDSetElement::kNewPacket);
00315 
00316    while ( fElem == 0 || fElemNum == 0 || fCur < fFirst-1 ) {
00317 
00318       if (gPerfStats && fFile) {
00319          Long64_t bytesRead = fFile->GetBytesRead();
00320          gPerfStats->SetBytesRead(bytesRead - fOldBytesRead);
00321          fOldBytesRead = bytesRead;
00322       }
00323 
00324       SafeDelete(fElem);
00325       fElem = fDSet->Next(fKeys->GetSize());
00326       if (fElem && fElem->GetEntryList()) {
00327          Error("GetNextEvent", "Entry- or event-list not available");
00328          return -1;
00329       }
00330 
00331       if ( fElem == 0 ) {
00332          fNum = 0;
00333          return -1;
00334       }
00335       fElem->SetBit(TDSetElement::kNewPacket);
00336 
00337       Int_t r = LoadDir();
00338 
00339       if ( r == -1 ) {
00340 
00341          // Error has been reported
00342          fNum = 0;
00343          return -1;
00344 
00345       } else if ( r == 1 ) {
00346 
00347          // New file and/or directory
00348          fKeys = fDir->GetListOfKeys();
00349          fNextKey = new TIter(fKeys);
00350       }
00351 
00352       // Validate values for this element
00353       fElemFirst = fElem->GetFirst();
00354       fElemNum = fElem->GetNum();
00355       fEntryList = dynamic_cast<TEntryList *>(fElem->GetEntryList());
00356       fEventList = (fEntryList) ? (TEventList *)0
00357                                 : dynamic_cast<TEventList *>(fElem->GetEntryList());
00358       fEventListPos = 0;
00359       if (fEventList)
00360          fElemNum = fEventList->GetN();
00361 
00362       Long64_t num = fKeys->GetSize();
00363 
00364       if ( fElemFirst > num ) {
00365          Error("GetNextEvent","First (%lld) higher then number of keys (%lld) in %s",
00366                fElemFirst, num, fElem->GetName());
00367          fNum = 0;
00368          return -1;
00369       }
00370 
00371       if ( fElemNum == -1 ) {
00372          fElemNum = num - fElemFirst;
00373       } else if ( fElemFirst+fElemNum  > num ) {
00374          Error("GetNextEvent","Num (%lld) + First (%lld) larger then number of keys (%lld) in %s",
00375             fElemNum, fElemFirst, num, fElem->GetDirectory());
00376          fElemNum = num - fElemFirst;
00377       }
00378 
00379       // Skip this element completely?
00380       if ( fCur + fElemNum < fFirst ) {
00381          fCur += fElemNum;
00382          continue;
00383       }
00384 
00385       // Position within this element. TODO: more efficient?
00386       fNextKey->Reset();
00387       for(fElemCur = -1; fElemCur < fElemFirst-1 ; fElemCur++, fNextKey->Next()) { }
00388    }
00389 
00390    --fElemNum;
00391    ++fElemCur;
00392    --fNum;
00393    ++fCur;
00394    TKey *key = (TKey*) fNextKey->Next();
00395    TDirectory *dirsave = gDirectory;
00396    fDir->cd();
00397    fObj = key->ReadObj();
00398    if (dirsave) dirsave->cd();
00399    fSel->SetObject( fObj );
00400 
00401    return fElemCur;
00402 }
00403 
00404 //------------------------------------------------------------------------
00405 
00406 //______________________________________________________________________________
00407 TEventIterTree::TFileTree::TFileTree(const char *name, TFile *f, Bool_t islocal)
00408                : TNamed(name, ""), fUsed(kFALSE), fIsLocal(islocal), fFile(f)
00409 {
00410    // Default ctor.
00411 
00412    fTrees = new TList;
00413    fTrees->SetOwner();
00414 }
00415 //______________________________________________________________________________
00416 TEventIterTree::TFileTree::~TFileTree()
00417 {
00418    // Default dtor.
00419 
00420    // Avoid destroying the cache; must be placed before deleting the trees
00421    fFile->SetCacheRead(0);
00422    SafeDelete(fTrees);
00423    SafeDelete(fFile);
00424 }
00425 
00426 ClassImp(TEventIterTree)
00427 
00428 //______________________________________________________________________________
00429 TEventIterTree::TEventIterTree()
00430 {
00431    // Default ctor.
00432 
00433    fTree = 0;
00434    fTreeCache = 0;
00435    fUseTreeCache = 1;
00436    fCacheSize = -1;
00437    fTreeCacheIsLearning = kTRUE;
00438    fUseParallelUnzip = 0;
00439 }
00440 
00441 //______________________________________________________________________________
00442 TEventIterTree::TEventIterTree(TDSet *dset, TSelector *sel, Long64_t first, Long64_t num)
00443    : TEventIter(dset,sel,first,num)
00444 {
00445    // Constructor
00446 
00447    fTreeName = dset->GetObjName();
00448    fTree = 0;
00449    fTreeCache = 0;
00450    fTreeCacheIsLearning = kTRUE;
00451    fFileTrees = new TList;
00452    fFileTrees->SetOwner();
00453    fUseTreeCache = gEnv->GetValue("ProofPlayer.UseTreeCache", 1);
00454    fCacheSize = gEnv->GetValue("ProofPlayer.CacheSize", -1);
00455    fUseParallelUnzip = gEnv->GetValue("ProofPlayer.UseParallelUnzip", 0);
00456    if (fUseParallelUnzip) {
00457       TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kEnable);
00458    } else {
00459       TTreeCacheUnzip::SetParallelUnzip(TTreeCacheUnzip::kDisable);
00460    }
00461 }
00462 
00463 //______________________________________________________________________________
00464 TEventIterTree::~TEventIterTree()
00465 {
00466    // Destructor
00467 
00468    // Delete the tree cache ...
00469    SafeDelete(fTreeCache);
00470    // ... and the remaining open files
00471    SafeDelete(fFileTrees);
00472 }
00473 
00474 //______________________________________________________________________________
00475 Long64_t TEventIterTree::GetCacheSize()
00476 {
00477    // Return the size in bytes of the cache, if any
00478    // Return -1 if not used
00479 
00480    if (fUseTreeCache) return fCacheSize;
00481    return -1;
00482 }
00483 
00484 //______________________________________________________________________________
00485 Int_t TEventIterTree::GetLearnEntries()
00486 {
00487    // Return the number of entries in the learning phase
00488 
00489    return TTreeCache::GetLearnEntries();
00490 }
00491 
00492 //______________________________________________________________________________
00493 TTree* TEventIterTree::GetTrees(TDSetElement *elem)
00494 {
00495    // Create a Tree for the main TDSetElement and for all the friends.
00496    // Returns the main tree or 0 in case of an error.
00497 
00498    // Reset used flags
00499    TIter nxft(fFileTrees);
00500    TFileTree *ft = 0;
00501    while ((ft = (TFileTree *)nxft()))
00502       ft->fUsed = kFALSE;
00503 
00504    Bool_t localfile = kFALSE;
00505    TTree* main = Load(elem, localfile);
00506 
00507    if (main && main != fTree) {
00508       // Set the file cache
00509       if (fUseTreeCache) {
00510          TFile *curfile = main->GetCurrentFile();
00511          if (!fTreeCache) {
00512             main->SetCacheSize(fCacheSize);
00513             fTreeCache = (TTreeCache *)curfile->GetCacheRead();
00514             if (fCacheSize < 0) fCacheSize = main->GetCacheSize();
00515          } else {
00516             curfile->SetCacheRead(fTreeCache);
00517             fTreeCache->UpdateBranches(main, kTRUE);
00518          }
00519          fTreeCacheIsLearning = fTreeCache->IsLearning();
00520          if (fTreeCacheIsLearning)
00521             Info("GetTrees","the tree cache is in learning phase");
00522       } else {
00523          // Disable the cache
00524          main->SetCacheSize(0);
00525       }
00526    }
00527    Bool_t loc = kFALSE;
00528    // Also the friends
00529    TList *friends = elem->GetListOfFriends();
00530    if (friends) {
00531       TIter nxf(friends);
00532       TDSetElement *dse = 0;
00533       while ((dse = (TDSetElement *) nxf())) {
00534          // The alias, if any, is in the element name options ('friend_alias=<alias>|')
00535          TUrl uf(dse->GetName());
00536          TString uo(uf.GetOptions()), alias;
00537          Int_t from = kNPOS;
00538          if ((from = uo.Index("friend_alias=")) != kNPOS) {
00539             from += strlen("friend_alias=");
00540             if (!uo.Tokenize(alias, from, "|"))
00541                Warning("GetTrees", "empty 'friend_alias' found for tree friend");
00542             // The options may be used for other things, so remove the internal strings once decoded
00543             uo.ReplaceAll(TString::Format("friend_alias=%s|", alias.Data()), "");
00544             uf.SetOptions(uo);
00545             dse->SetName(uf.GetUrl());
00546          }
00547          TTree *friendTree = Load(dse, loc);
00548          if (friendTree && main) {
00549             // Make sure it has not yet been added
00550             Bool_t addfriend = kTRUE;
00551             TList *frnds = main->GetListOfFriends();
00552             if (frnds) {
00553                TIter xnxf(frnds);
00554                TFriendElement *fe = 0;
00555                while ((fe = (TFriendElement *) xnxf())) {
00556                   if (fe->GetTree() == friendTree) {
00557                      addfriend = kFALSE;
00558                      break;
00559                   }
00560                }
00561             }
00562             if (addfriend) {
00563                if (alias.IsNull())
00564                   main->AddFriend(friendTree);
00565                else
00566                   main->AddFriend(friendTree, alias);
00567             }
00568          } else {
00569             return 0;
00570          }
00571       }
00572    }
00573 
00574    // Remove instances not used
00575    nxft.Reset();
00576    while ((ft = (TFileTree *)nxft())) {
00577       if (!(ft->fUsed)) {
00578          fFileTrees->Remove(ft);
00579          delete ft;
00580       } else {
00581       }
00582    }
00583 
00584    // Done, successfully or not
00585    return main;
00586 }
00587 
00588 //______________________________________________________________________________
00589 TTree* TEventIterTree::Load(TDSetElement *e, Bool_t &localfile)
00590 {
00591    // Load a tree from s TDSetElement
00592 
00593    if (!e) {
00594       Error("Load", "undefined element");
00595       return (TTree *)0;
00596    }
00597 
00598    const char *fn = e->GetFileName();
00599    const char *dn = e->GetDirectory();
00600    const char *tn = e->GetObjName();
00601 
00602    TFile *f = 0;
00603 
00604    // Check if the file is already open
00605    TString names(fn);
00606    TString name;
00607    Ssiz_t from = 0;
00608    TFileTree *ft = 0;
00609    while (names.Tokenize(name,from,"|")) {
00610       TString key(TUrl(name).GetFileAndOptions());
00611       if ((ft = (TFileTree *) fFileTrees->FindObject(key.Data()))) {
00612          f = ft->fFile;
00613          break;
00614       }
00615    }
00616 
00617    // Open the file, if needed
00618    if (!f) {
00619       TFile::EFileType typ = TFile::kDefault;
00620       TString fname = gEnv->GetValue("Path.Localroot","");
00621       if (!fname.IsNull())
00622          typ = TFile::GetType(fn, "", &fname);
00623       if (typ != TFile::kLocal) {
00624          fname = fn;
00625       } else {
00626          localfile = kTRUE;
00627       }
00628 
00629       // Open the file
00630       f = TFile::Open(fname);
00631       if (!f) {
00632          Error("Load","file '%s' ('%s') could not be open", fn, fname.Data());
00633          return (TTree *)0;
00634       }
00635 
00636       // Create TFileTree instance in the list
00637       ft = new TFileTree(TUrl(f->GetName()).GetFileAndOptions(), f, localfile);
00638       fFileTrees->Add(ft);
00639    } else {
00640       // Fill locality boolean
00641       localfile = ft->fIsLocal;
00642    }
00643 
00644    // Check if the tree is already loaded
00645    if (ft && ft->fTrees->GetSize() > 0) {
00646       TTree *t = 0;
00647       if (!strcmp(tn, "*"))
00648          t = (TTree *) ft->fTrees->First();
00649       else
00650          t = (TTree *) ft->fTrees->FindObject(tn);
00651       if (t) {
00652          ft->fUsed = kTRUE;
00653          return t;
00654       }
00655    }
00656 
00657    TDirectory *dd = f;
00658    // Change dir, if required
00659    if (dn && !(dd = f->GetDirectory(dn))) {
00660       Error("Load","Cannot get to: %s", dn);
00661       return (TTree *)0;
00662    }
00663    PDB(kLoop,2)
00664       Info("Load","got directory: %s", dn);
00665 
00666    // If a wild card we will use the first object of the type
00667    // requested compatible with the reg expression we got
00668    TString on(tn);
00669    TString sreg(tn);
00670    if (sreg.Length() <= 0 || sreg == "" || sreg.Contains("*")) {
00671       if (sreg.Contains("*"))
00672          sreg.ReplaceAll("*", ".*");
00673       else
00674          sreg = ".*";
00675       TRegexp re(sreg);
00676       if (dd->GetListOfKeys()) {
00677          TIter nxk(dd->GetListOfKeys());
00678          TKey *k = 0;
00679          while ((k = (TKey *) nxk())) {
00680             if (!strcmp(k->GetClassName(), "TTree")) {
00681                TString kn(k->GetName());
00682                if (kn.Index(re) != kNPOS) {
00683                   on = kn;
00684                   break;
00685                }
00686             }
00687          }
00688       }
00689    }
00690 
00691    // Point to the key
00692    TKey *key = dd->GetKey(on);
00693    if (key == 0) {
00694       Error("Load", "Cannot find tree \"%s\" in %s", tn, fn);
00695       return (TTree*)0;
00696    }
00697 
00698    PDB(kLoop,2) Info("Load", "Reading: %s", tn);
00699 
00700    TTree *tree = dynamic_cast<TTree*> (key->ReadObj());
00701    dd->cd();
00702 
00703    if (tree == 0) {
00704       Error("Load", "Cannot <dynamic_cast> obj to tree \"%s\"", tn);
00705       return (TTree*)0;
00706    }
00707 
00708    // Add track in the cache
00709    ft->fTrees->Add(tree);
00710    ft->fUsed = kTRUE;
00711    PDB(kLoop,2)
00712       Info("Load","TFileTree for '%s' flagged as 'in-use' ...", ft->GetName());
00713 
00714    // Done
00715    return tree;
00716 }
00717 
00718 //______________________________________________________________________________
00719 Long64_t TEventIterTree::GetNextEvent()
00720 {
00721    // Get next event
00722 
00723    if (fStop || fNum == 0) return -1;
00724 
00725    Bool_t attach = kFALSE;
00726 
00727    if (fElem) fElem->ResetBit(TDSetElement::kNewPacket);
00728 
00729    while ( fElem == 0 || fElemNum == 0 || fCur < fFirst-1 ) {
00730 
00731       if (gPerfStats && fTree) {
00732          Long64_t totBytesRead = fTree->GetCurrentFile()->GetBytesRead();
00733          Long64_t bytesRead = totBytesRead - fOldBytesRead;
00734          gPerfStats->SetBytesRead(bytesRead);
00735          fOldBytesRead = totBytesRead;
00736       }
00737 
00738       SafeDelete(fElem);
00739       while (!fElem) {
00740          if (fTree) {
00741             fElem = fDSet->Next(fTree->GetEntries());
00742          } else {
00743             fElem = fDSet->Next();
00744          }
00745 
00746          if (!fElem) {
00747             // End of processing
00748             fNum = 0;
00749             return -1;
00750          }
00751          fElem->SetBit(TDSetElement::kNewPacket);
00752 
00753          TTree *newTree = GetTrees(fElem);
00754          if (newTree) {
00755             if (newTree != fTree) {
00756                // The old tree is owned by TFileTree and will be deleted there
00757                fTree = newTree;
00758                attach = kTRUE;
00759                fOldBytesRead = fTree->GetCurrentFile()->GetBytesRead();
00760             }
00761             // Set range to be analysed
00762             if (fTreeCache)
00763                fTreeCache->SetEntryRange(fElem->GetFirst(),
00764                                          fElem->GetFirst() + fElem->GetNum() - 1);
00765          } else {
00766             // Could not open this element: ask for another one
00767             SafeDelete(fElem);
00768             // The current tree, if any, is not valid anymore
00769             fTree = 0;
00770          }
00771       }
00772 
00773       // Validate values for this element
00774       fElemFirst = fElem->GetFirst();
00775       fElemNum = fElem->GetNum();
00776       fEntryList = dynamic_cast<TEntryList *>(fElem->GetEntryList());
00777       fEventList = (fEntryList) ? (TEventList *)0
00778                                 : dynamic_cast<TEventList *>(fElem->GetEntryList());
00779       fEntryListPos = fElemFirst;
00780       fEventListPos = 0;
00781       if (fEntryList)
00782          fElemNum = fEntryList->GetEntriesToProcess();
00783       else if (fEventList)
00784          fElemNum = fEventList->GetN();
00785 
00786       Long64_t num = (Long64_t) fTree->GetEntries();
00787 
00788       if (!fEntryList && !fEventList) {
00789          if ( fElemFirst > num ) {
00790             Error("GetNextEvent", "first (%lld) higher then number of entries (%lld) in %s",
00791                                   fElemFirst, num, fElem->GetObjName());
00792             fNum = 0;
00793             return -1;
00794          }
00795          if ( fElemNum == -1 ) {
00796             fElemNum = num - fElemFirst;
00797          } else if ( fElemFirst+fElemNum  > num ) {
00798             Error("GetNextEvent", "num (%lld) + first (%lld) larger then number of entries (%lld) in %s",
00799                                   fElemNum, fElemFirst, num, fElem->GetName());
00800             fElemNum = num - fElemFirst;
00801          }
00802 
00803          // Skip this element completely?
00804          if ( fCur + fElemNum < fFirst ) {
00805             fCur += fElemNum;
00806             continue;
00807          }
00808          // Position within this element. TODO: more efficient?
00809          fElemCur = fElemFirst-1;
00810       }
00811    }
00812 
00813    if ( attach ) {
00814       PDB(kLoop,1) Info("GetNextEvent", "call Init(%p) and Notify()",fTree);
00815       fSel->Init(fTree);
00816       fSel->Notify();
00817       TIter next(fSel->GetOutputList());
00818       TEntryList *elist=0;
00819       while ((elist=(TEntryList*)next())){
00820          if (elist->InheritsFrom(TEntryList::Class()))
00821             elist->SetTree(fTree->GetName(), fElem->GetFileName());
00822       }
00823       if (fSel->GetAbort() == TSelector::kAbortProcess) {
00824          // the error has been reported
00825          return -1;
00826       }
00827       attach = kFALSE;
00828    }
00829    Long64_t rv;
00830 
00831    if (fEntryList){
00832       --fElemNum;
00833       rv = fEntryList->GetEntry(fEntryListPos);
00834       fEntryListPos++;
00835    } else if (fEventList) {
00836       --fElemNum;
00837       rv = fEventList->GetEntry(fEventListPos);
00838       fEventListPos++;
00839    } else {
00840       --fElemNum;
00841       ++fElemCur;
00842       --fNum;
00843       ++fCur;
00844       rv = fElemCur;
00845    }
00846 
00847    // Signal ending of learning phase
00848    if (fTreeCache && fTreeCacheIsLearning) {
00849       if (!(fTreeCache->IsLearning())) {
00850          fTreeCacheIsLearning = kFALSE;
00851          if (gProofServ) gProofServ->RestartComputeTime();
00852       }
00853    }
00854 
00855    // For prefetching
00856    fTree->LoadTree(rv);
00857 
00858    return rv;
00859 }

Generated on Tue Jul 5 14:52:17 2011 for ROOT_528-00b_version by  doxygen 1.5.1