#include "TTreeCache.h"
#include "TChain.h"
#include "TBranch.h"
#include "TEventList.h"
#include "TObjString.h"
Int_t TTreeCache::fgLearnEntries = 100;
ClassImp(TTreeCache)
TTreeCache::TTreeCache() : TFileCacheRead(),
fEntryMin(0),
fEntryMax(1),
fEntryNext(1),
fZipBytes(0),
fNbranches(0),
fNReadOk(0),
fNReadMiss(0),
fNReadPref(0),
fBranches(0),
fBrNames(0),
fOwner(0),
fTree(0),
fIsLearning(kTRUE)
{
}
TTreeCache::TTreeCache(TTree *tree, Int_t buffersize) : TFileCacheRead(tree->GetCurrentFile(),buffersize),
fEntryMin(0),
fEntryMax(tree->GetEntriesFast()),
fEntryNext(0),
fZipBytes(0),
fNbranches(0),
fNReadOk(0),
fNReadMiss(0),
fNReadPref(0),
fBranches(0),
fBrNames(new TList),
fOwner(tree),
fTree(0),
fIsLearning(kTRUE)
{
fEntryNext = fEntryMin + fgLearnEntries;
Int_t nleaves = tree->GetListOfLeaves()->GetEntries();
fBranches = new TBranch*[nleaves+10];
}
TTreeCache::~TTreeCache()
{
delete [] fBranches;
if (fBrNames) {fBrNames->Delete(); delete fBrNames; fBrNames=0;}
}
void TTreeCache::AddBranch(TBranch *b)
{
if (!fIsLearning) return;
Bool_t isNew = kTRUE;
for (int i=0;i<fNbranches;i++) {
if (fBranches[i] == b) {isNew = kFALSE; break;}
}
if (isNew) {
fTree = b->GetTree();
fBranches[fNbranches] = b;
fBrNames->Add(new TObjString(b->GetName()));
fZipBytes += b->GetZipBytes();
fNbranches++;
if (gDebug > 0) printf("Entry: %lld, registering branch: %s\n",b->GetTree()->GetReadEntry(),b->GetName());
}
}
Bool_t TTreeCache::FillBuffer()
{
if (fNbranches <= 0) return kFALSE;
TTree *tree = fBranches[0]->GetTree();
Long64_t entry = tree->GetReadEntry();
if (entry < fEntryNext) return kFALSE;
fEntryNext = entry + tree->GetEntries()*fBufferSizeMin/fZipBytes;
if (fEntryMax <= 0) fEntryMax = tree->GetEntries();
if (fEntryNext > fEntryMax) fEntryNext = fEntryMax+1;
TEventList *elist = fOwner->GetEventList();
Long64_t chainOffset = 0;
if (elist) {
if (fOwner->IsA() ==TChain::Class()) {
TChain *chain = (TChain*)fOwner;
Int_t t = chain->GetTreeNumber();
chainOffset = chain->GetTreeOffset()[t];
}
}
TFileCacheRead::Prefetch(0,0);
Bool_t mustBreak = kFALSE;
for (Int_t i=0;i<fNbranches;i++) {
if (mustBreak) break;
TBranch *b = fBranches[i];
Int_t nb = b->GetMaxBaskets();
Int_t *lbaskets = b->GetBasketBytes();
Long64_t *entries = b->GetBasketEntry();
if (!lbaskets || !entries) continue;
for (Int_t j=0;j<nb;j++) {
Long64_t pos = b->GetBasketSeek(j);
Int_t len = lbaskets[j];
if (pos <= 0 || len <= 0) continue;
if (entries[j] > fEntryNext) continue;
if (entries[j] < entry && (j<nb-1 && entries[j+1] < entry)) continue;
if (elist) {
Long64_t emax = fEntryMax;
if (j<nb-1) emax = entries[j+1]-1;
if (!elist->ContainsRange(entries[j]+chainOffset,emax+chainOffset)) continue;
}
fNReadPref++;
TFileCacheRead::Prefetch(pos,len);
if (fNtot > 2*fBufferSizeMin) {TFileCacheRead::Prefetch(0,0);mustBreak = kTRUE; break;}
}
if (gDebug > 0) printf("Entry: %lld, registering baskets branch %s, fEntryNext=%lld, fNseek=%d, fNtot=%d\n",entry,fBranches[i]->GetName(),fEntryNext,fNseek,fNtot);
}
fIsLearning = kFALSE;
if (mustBreak) return kFALSE;
return kTRUE;
}
Double_t TTreeCache::GetEfficiency()
{
if ( !fNReadPref )
return 0;
return ((Double_t)fNReadOk / (Double_t)fNReadPref);
}
Double_t TTreeCache::GetEfficiencyRel()
{
if ( !fNReadOk && !fNReadMiss )
return 0;
return ((Double_t)fNReadOk / (Double_t)(fNReadOk + fNReadMiss));
}
Int_t TTreeCache::GetLearnEntries()
{
return fgLearnEntries;
}
TTree *TTreeCache::GetTree() const
{
if (fNbranches <= 0) return 0;
return fBranches[0]->GetTree();
}
Int_t TTreeCache::ReadBuffer(char *buf, Long64_t pos, Int_t len)
{
if (TFileCacheRead::ReadBuffer(buf,pos,len) == 1){
fNReadOk++;
return 1;
}
Bool_t bufferFilled = FillBuffer();
if (bufferFilled) {
Int_t res = TFileCacheRead::ReadBuffer(buf,pos,len);
if (res == 1)
fNReadOk++;
else if (res == 0)
fNReadMiss++;
return res;
}
fNReadMiss++;
return 0;
}
void TTreeCache::SetEntryRange(Long64_t emin, Long64_t emax)
{
fEntryMin = emin;
fEntryMax = emax;
fEntryNext = fEntryMin + fgLearnEntries;
if (gDebug > 0) printf("SetEntryRange: fEntryMin=%lld, fEntryMax=%lld, fEntryNext=%lld\n",fEntryMin,fEntryMax,fEntryNext);
fIsLearning = kTRUE;
fNbranches = 0;
fZipBytes = 0;
if (fBrNames) fBrNames->Delete();
}
void TTreeCache::SetLearnEntries(Int_t n)
{
if (n < 1) n = 1;
fgLearnEntries = n;
}
void TTreeCache::UpdateBranches(TTree *tree)
{
fTree = tree;
fEntryMin = 0;
fEntryMax = fTree->GetEntries();
fEntryNext = fEntryMin + fgLearnEntries;
fZipBytes = 0;
fNbranches = 0;
TIter next(fBrNames);
TObjString *os;
while ((os = (TObjString*)next())) {
TBranch *b = fTree->GetBranch(os->GetName());
if (!b) continue;
fBranches[fNbranches] = b;
fZipBytes += b->GetZipBytes();
fNbranches++;
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.