Logo ROOT  
Reference Guide
TTreeCloner.cxx
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Philippe Canal 07/11/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TTreeCloner
13\ingroup tree
14
15Class implementing or helping the various TTree cloning method
16*/
17
18#include "TBasket.h"
19#include "TBranch.h"
20#include "TBranchClones.h"
21#include "TBranchElement.h"
22#include "TStreamerInfo.h"
23#include "TBranchRef.h"
24#include "TError.h"
25#include "TProcessID.h"
26#include "TMath.h"
27#include "TTree.h"
28#include "TTreeCloner.h"
29#include "TFile.h"
30#include "TLeafB.h"
31#include "TLeafI.h"
32#include "TLeafL.h"
33#include "TLeafS.h"
34#include "TLeafO.h"
35#include "TLeafC.h"
36#include "TFileCacheRead.h"
37#include "TTreeCache.h"
38
39#include <algorithm>
40
41////////////////////////////////////////////////////////////////////////////////
42
44{
45 if (fObject->fBasketSeek[i1] == fObject->fBasketSeek[i2]) {
46 if (fObject->fBasketEntry[i1] == fObject->fBasketEntry[i2]) {
47 return i1 < i2;
48 }
49 return fObject->fBasketEntry[i1] < fObject->fBasketEntry[i2];
50 }
51 return fObject->fBasketSeek[i1] < fObject->fBasketSeek[i2];
52}
53
54////////////////////////////////////////////////////////////////////////////////
55
57{
58 if (fObject->fBasketEntry[i1] == fObject->fBasketEntry[i2]) {
59 return i1 < i2;
60 }
61 return fObject->fBasketEntry[i1] < fObject->fBasketEntry[i2];
62}
63
64////////////////////////////////////////////////////////////////////////////////
65/// Constructor. This object would transfer the data from
66/// 'from' to 'to' using the method indicated in method.
67///
68/// The value of the parameter 'method' determines in which
69/// order the branches' baskets are written to the output file.
70///
71/// When a TTree is filled the data is stored in the individual
72/// branches' basket. Each basket is written individually to
73/// the disk as soon as it is full. In consequence the baskets
74/// of branches that contain 'large' data chunk are written to
75/// the disk more often.
76///
77/// There is currently 3 supported sorting order:
78///
79/// SortBasketsByOffset (the default)
80/// SortBasketsByBranch
81/// SortBasketsByEntry
82///
83/// When using SortBasketsByOffset the baskets are written in
84/// the output file in the same order as in the original file
85/// (i.e. the basket are sorted on their offset in the original
86/// file; Usually this also means that the baskets are sorted
87/// on the index/number of the _last_ entry they contain)
88///
89/// When using SortBasketsByBranch all the baskets of each
90/// individual branches are stored contiguously. This tends to
91/// optimize reading speed when reading a small number (1->5) of
92/// branches, since all their baskets will be clustered together
93/// instead of being spread across the file. However it might
94/// decrease the performance when reading more branches (or the full
95/// entry).
96///
97/// When using SortBasketsByEntry the baskets with the lowest
98/// starting entry are written first. (i.e. the baskets are
99/// sorted on the index/number of the first entry they contain).
100/// This means that on the file the baskets will be in the order
101/// in which they will be needed when reading the whole tree
102/// sequentially.
103
104TTreeCloner::TTreeCloner(TTree *from, TTree *to, Option_t *method, UInt_t options) :
105 fWarningMsg(),
108 fOptions(options),
109 fFromTree(from),
110 fToTree(to),
111 fMethod(method),
112 fFromBranches( from ? from->GetListOfLeaves()->GetEntries()+1 : 0),
113 fToBranches( to ? to->GetListOfLeaves()->GetEntries()+1 : 0),
120 fPidOffset(0),
123 fCacheSize(0LL),
124 fFileCache(nullptr),
125 fPrevCache(nullptr)
126{
127 TString opt(method);
128 opt.ToLower();
129 if (opt.Contains("sortbasketsbybranch")) {
130 //::Info("TTreeCloner::TTreeCloner","use: kSortBasketsByBranch");
132 } else if (opt.Contains("sortbasketsbyentry")) {
133 //::Info("TTreeCloner::TTreeCloner","use: kSortBasketsByEntry");
135 } else {
136 //::Info("TTreeCloner::TTreeCloner","use: kSortBasketsByOffset");
138 }
140
141 if (fFromTree == nullptr) {
142 if (to)
143 fWarningMsg.Form("An input TTree is required (cloning to %s).",
144 to->GetName());
145 else
146 fWarningMsg.Form("An input and output TTree are required.");
147 if (!(fOptions & kNoWarnings)) {
148 Warning("TTreeCloner::TTreeCloner", "%s", fWarningMsg.Data());
149 }
151 }
152 if (fToTree == nullptr) {
153 fWarningMsg.Form("An output TTree is required (cloning %s).",
154 from ? from->GetName() : "no tree");
155 if (!(fOptions & kNoWarnings)) {
156 Warning("TTreeCloner::TTreeCloner", "%s", fWarningMsg.Data());
157 }
159 } else if (fToTree->GetDirectory() == nullptr) {
160 fWarningMsg.Form("The output TTree (%s) must be associated with a directory.",
161 fToTree->GetName());
162 if (!(fOptions & kNoWarnings)) {
163 Warning("TTreeCloner::TTreeCloner", "%s", fWarningMsg.Data());
164 }
166 } else if (fToTree->GetCurrentFile() == nullptr) {
167 fWarningMsg.Form("The output TTree (%s) must be associated with a directory (%s) that is in a file.",
169 if (!(fOptions & kNoWarnings)) {
170 Warning("TTreeCloner::TTreeCloner", "%s", fWarningMsg.Data());
171 }
173 } else if (! fToTree->GetDirectory()->IsWritable()) {
175 fWarningMsg.Form("The output TTree (%s) must be associated with a writable file (%s).",
177 } else {
178 fWarningMsg.Form("The output TTree (%s) must be associated with a writable directory (%s in %s).",
180 }
181 if (!(fOptions & kNoWarnings)) {
182 Warning("TTreeCloner::TTreeCloner", "%s", fWarningMsg.Data());
183 }
185 }
186
187 if (fIsValid && (!(fOptions & kNoFileCache))) {
189 }
190}
191
192////////////////////////////////////////////////////////////////////////////////
193/// Execute the cloning.
194
196{
197 if (!IsValid()) {
198 return kFALSE;
199 }
200 CreateCache();
206 SortBaskets();
207 WriteBaskets();
209 RestoreCache();
210
211 return kTRUE;
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// TTreeCloner destructor
216
218{
219 // The file cache was restored to its previous value at the end of Exec,
220 // we can safely delete our cache.
221 delete fFileCache;
222 delete [] fBasketBranchNum;
223 delete [] fBasketNum;
224 delete [] fBasketSeek;
225 delete [] fBasketEntry;
226 delete [] fBasketIndex;
227}
228
229////////////////////////////////////////////////////////////////////////////////
230/// Before we can start adding new basket, we need to flush to
231/// disk the partially filled baskets (the WriteBasket)
232
234{
235 for(Int_t i=0; i<fToBranches.GetEntries(); ++i) {
238 }
239}
240
241////////////////////////////////////////////////////////////////////////////////
242/// Fill the array of branches, adding the branch 'from' and 'to',
243/// and matching the sub-branches of the 'from' and 'to' branches.
244/// Returns the total number of baskets in all the from branch and
245/// it sub-branches.
246
248 // Since this is called from the constructor, this can not be a virtual function
249
250 UInt_t numBaskets = 0;
251 if (from->InheritsFrom(TBranchClones::Class())) {
252 TBranchClones *fromclones = (TBranchClones*) from;
253 TBranchClones *toclones = (TBranchClones*) to;
254 numBaskets += CollectBranches(fromclones->fBranchCount, toclones->fBranchCount);
255
256 } else if (from->InheritsFrom(TBranchElement::Class())) {
257 Int_t nb = from->GetListOfLeaves()->GetEntries();
258 Int_t fnb = to->GetListOfLeaves()->GetEntries();
259 if (nb != fnb && (nb == 0 || fnb == 0)) {
260 // We might be in the case where one branch is split
261 // while the other is not split. We must reject this match.
262 fWarningMsg.Form("The export branch and the import branch do not have the same split level. (The branch name is %s.)",
263 from->GetName());
264 if (!(fOptions & kNoWarnings)) {
265 Warning("TTreeCloner::CollectBranches", "%s", fWarningMsg.Data());
266 }
269 return 0;
270 }
271 if (((TBranchElement*) from)->GetStreamerType() != ((TBranchElement*) to)->GetStreamerType()) {
272 fWarningMsg.Form("The export branch and the import branch do not have the same streamer type. (The branch name is %s.)",
273 from->GetName());
274 if (!(fOptions & kNoWarnings)) {
275 Warning("TTreeCloner::CollectBranches", "%s", fWarningMsg.Data());
276 }
278 return 0;
279 }
280 TBranchElement *fromelem = (TBranchElement*) from;
281 TBranchElement *toelem = (TBranchElement*) to;
282 if (fromelem->fMaximum > toelem->fMaximum) toelem->fMaximum = fromelem->fMaximum;
283 } else {
284
285 Int_t nb = from->GetListOfLeaves()->GetEntries();
286 Int_t fnb = to->GetListOfLeaves()->GetEntries();
287 if (nb != fnb) {
288 fWarningMsg.Form("The export branch and the import branch (%s) do not have the same number of leaves (%d vs %d)",
289 from->GetName(), fnb, nb);
290 if (!(fOptions & kNoWarnings)) {
291 Error("TTreeCloner::CollectBranches", "%s", fWarningMsg.Data());
292 }
294 return 0;
295 }
296 for (Int_t i=0;i<nb;i++) {
297
298 TLeaf *fromleaf = (TLeaf*)from->GetListOfLeaves()->At(i);
299 TLeaf *toleaf = (TLeaf*)to->GetListOfLeaves()->At(i);
300 if (toleaf->IsA() != fromleaf->IsA() ) {
301 // The data type do not match, we can not do a fast merge.
302 fWarningMsg.Form("The export leaf and the import leaf (%s.%s) do not have the data type (%s vs %s)",
303 from->GetName(),fromleaf->GetName(),fromleaf->GetTypeName(),toleaf->GetTypeName());
304 if (! (fOptions & kNoWarnings) ) {
305 Warning("TTreeCloner::CollectBranches", "%s", fWarningMsg.Data());
306 }
309 return 0;
310 }
311 toleaf->IncludeRange( fromleaf );
312 }
313
314 }
315
318 // Make sure that we reset the Buffer's map if needed.
320 }
322
323 numBaskets += from->GetWriteBasket();
324 numBaskets += CollectBranches(from->GetListOfBranches(),to->GetListOfBranches());
325
326 return numBaskets;
327}
328
329////////////////////////////////////////////////////////////////////////////////
330/// Fill the array of branches, matching the branches of the 'from' and 'to' arrays.
331/// Returns the total number of baskets in all the branches.
332
334{
335 // Since this is called from the constructor, this can not be a virtual function
336
337 Int_t fnb = from->GetEntries();
338 Int_t tnb = to->GetEntries();
339 if (!fnb || !tnb) {
340 return 0;
341 }
342
343 UInt_t numBasket = 0;
344 Int_t fi = 0;
345 Int_t ti = 0;
346 while (ti < tnb) {
347 TBranch* fb = (TBranch*) from->UncheckedAt(fi);
348 TBranch* tb = (TBranch*) to->UncheckedAt(ti);
349 Int_t firstfi = fi;
350 while (strcmp(fb->GetName(), tb->GetName())) {
351 ++fi;
352 if (fi >= fnb) {
353 // continue at the beginning
354 fi = 0;
355 }
356 if (fi==firstfi) {
357 // We tried all the branches and there is not match.
358 fb = 0;
359 break;
360 }
361 fb = (TBranch*) from->UncheckedAt(fi);
362 }
363 if (fb) {
364 numBasket += CollectBranches(fb, tb);
365 ++fi;
366 if (fi >= fnb) {
367 fi = 0;
368 }
369 } else {
370 if (tb->GetMother()==tb) {
371 // Top level branch.
373 fWarningMsg.Form("One of the export top level branches (%s) is not present in the import TTree.",
374 tb->GetName());
375 if (!(fOptions & kNoWarnings)) {
376 Error("TTreeCloner::CollectBranches", "%s", fWarningMsg.Data());
377 }
379 }
380 } else {
381 fWarningMsg.Form("One of the export sub-branches (%s) is not present in the import TTree.",
382 tb->GetName());
383 if (!(fOptions & kNoWarnings)) {
384 Error("TTreeCloner::CollectBranches", "%s", fWarningMsg.Data());
385 }
387 }
388 }
389 ++ti;
390 }
391 return numBasket;
392}
393
394////////////////////////////////////////////////////////////////////////////////
395/// Fill the array of branches, matching the branches of the 'from' and 'to' TTrees
396/// Returns the total number of baskets in all the branches.
397
399{
400 // Since this is called from the constructor, this can not be a virtual function
401
402 if (!fFromTree || !fToTree) {
403 return 0;
404 }
407
408 if (fFromTree->GetBranchRef()) {
411 }
412 return numBasket;
413}
414
415////////////////////////////////////////////////////////////////////////////////
416/// Collect the information about the on-file basket that need
417/// to be copied.
418
420{
422
423 for(UInt_t i=0,bi=0; i<len; ++i) {
425 for(Int_t b=0; b<from->GetWriteBasket(); ++b,++bi) {
426 fBasketBranchNum[bi] = i;
427 fBasketNum[bi] = b;
428 fBasketSeek[bi] = from->GetBasketSeek(b);
429 //fprintf(stderr,"For %s %d %lld\n",from->GetName(),bi,fBasketSeek[bi]);
430 fBasketEntry[bi] = from->GetBasketEntry()[b];
431 fBasketIndex[bi] = bi;
432 }
433 }
434}
435
436////////////////////////////////////////////////////////////////////////////////
437/// Make sure that all the needed TStreamerInfo are
438/// present in the output file
439
441{
442 TFile *fromFile = fFromTree->GetDirectory()->GetFile();
443 TFile *toFile = fToTree->GetDirectory()->GetFile();
444 TList *l = fromFile->GetStreamerInfoList();
445 TIter next(l);
446 TStreamerInfo *oldInfo;
447 while ( (oldInfo = (TStreamerInfo*)next()) ) {
448 if (oldInfo->IsA() != TStreamerInfo::Class()) {
449 continue;
450 }
451 TStreamerInfo *curInfo = 0;
452 TClass *cl = TClass::GetClass(oldInfo->GetName());
453
454 if (!cl->IsLoaded() || cl->GetNew()) {
455 // Insure that the TStreamerInfo is loaded
456 curInfo = (TStreamerInfo*)cl->GetStreamerInfo(oldInfo->GetClassVersion());
457 if (oldInfo->GetClassVersion()==1) {
458 // We may have a Foreign class let's look using the
459 // checksum:
460 TStreamerInfo *matchInfo = (TStreamerInfo*)cl->FindStreamerInfo(oldInfo->GetCheckSum());
461 if (matchInfo) {
462 curInfo = matchInfo;
463 }
464 }
465 curInfo->ForceWriteInfo(toFile);
466 } else {
467 // If there is no default constructor the GetStreamerInfo
468 // will not work. It also means (hopefully) that an
469 // inheriting class has a streamerInfo in the list (which
470 // will induces the setting of this streamerInfo)
471
472 oldInfo->ForceWriteInfo(toFile);
473 }
474 }
475 delete l;
476}
477
478////////////////////////////////////////////////////////////////////////////////
479/// Transfer the basket from the input file to the output file
480
482{
483 TBasket *basket = 0;
484 for(Int_t i=0; i<fToBranches.GetEntries(); ++i) {
487
488 basket = from->GetListOfBaskets()->GetEntries() ? from->GetBasket(from->GetWriteBasket()) : 0;
489 if (basket) {
490 basket = (TBasket*)basket->Clone();
491 basket->SetBranch(to);
492 to->AddBasket(*basket, kFALSE, fToStartEntries+from->GetBasketEntry()[from->GetWriteBasket()]);
493 } else {
495 }
496 // In older files, if the branch is a TBranchElement non-terminal 'object' branch, it's basket will contain 0
497 // events, in newer file in the same case, the write basket will be missing.
498 if (from->GetEntries()!=0 && from->GetWriteBasket()==0 && (basket==0 || basket->GetNevBuf()==0)) {
499 to->SetEntries(to->GetEntries()+from->GetEntries());
500 }
501 }
502}
503
504////////////////////////////////////////////////////////////////////////////////
505/// Make sure that all the needed TStreamerInfo are
506/// present in the output file
507
509{
510 // NOTE: We actually need to merge the ProcessId somehow :(
511
512 TFile *fromfile = fFromTree->GetDirectory()->GetFile();
513 TFile *tofile = fToTree->GetDirectory()->GetFile();
514
515 fPidOffset = tofile->GetNProcessIDs();
516
517 TIter next(fromfile->GetListOfKeys());
518 TKey *key;
519 TDirectory::TContext cur(fromfile);
520 while ((key = (TKey*)next())) {
521 if (!strcmp(key->GetClassName(),"TProcessID")) {
522 TProcessID *pid = (TProcessID*)key->ReadObjectAny(0);
523 if (!pid) continue;
524
525 //UShort_t out = TProcessID::WriteProcessID(id,tofile);
526 UShort_t out = 0;
527 TObjArray *pids = tofile->GetListOfProcessIDs();
528 Int_t npids = tofile->GetNProcessIDs();
529 Bool_t wasIn = kFALSE;
530 for (Int_t i=0;i<npids;i++) {
531 if (pids->At(i) == pid) {out = (UShort_t)i; wasIn = kTRUE; break;}
532 }
533
534 if (!wasIn) {
535 TDirectory *dirsav = gDirectory;
536 tofile->cd();
538 pids->AddAtAndExpand(pid,npids);
539 pid->IncrementCount();
540 char name[32];
541 snprintf(name,32,"ProcessID%d",npids);
542 pid->Write(name);
543 tofile->IncrementProcessIDs();
544 if (gDebug > 0) {
545 Info("WriteProcessID", "name=%s, file=%s", name, tofile->GetName());
546 }
547 if (dirsav) dirsav->cd();
548 out = (UShort_t)npids;
549 }
550 if (out<fPidOffset) {
551 Error("CopyProcessIDs","Copied %s from %s might already exist!\n",
552 pid->GetName(),fromfile->GetName());
553 }
554 }
555 }
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// Create a TFileCacheRead if it was requested.
560
562{
565 auto prev = fFromTree->GetReadCache(f);
566 if (fFileCache && prev == fFileCache) {
567 return;
568 }
569 fPrevCache = prev;
570 // Remove the previous cache if any.
571 if (prev) f->SetCacheRead(nullptr, fFromTree);
572 // The constructor attach the new cache.
574 }
575}
576
577////////////////////////////////////////////////////////////////////////////////
578/// Restore the TFileCacheRead to its previous value.
579
583 f->SetCacheRead(nullptr,fFromTree); // Remove our file cache.
584 f->SetCacheRead(fPrevCache, fFromTree);
585 }
586}
587
588////////////////////////////////////////////////////////////////////////////////
589/// Set the entries and import the cluster range of the
590
592{
593 // First undo, the external call to SetEntries
594 // We could improve the interface to optional tell the TTreeCloner that the
595 // SetEntries was not done.
597
599
600 // This is only updated by TTree::Fill upon seeing a Flush event in TTree::Fill
601 // So we need to propagate (this has also the advantage of turning on the
602 // history recording feature of SetAutoFlush for the next iteration)
604
606}
607
608////////////////////////////////////////////////////////////////////////////////
609/// Set the TFile cache size to be used.
610/// Note that the default is to use the same size as the default TTreeCache for
611/// the input tree.
612/// \param size Size of the cache. Zero disable the use of the cache.
613
615{
616 fCacheSize = size;
617 if (IsValid() && fFileCache) {
618 if (fCacheSize == 0 || fCacheSize != fFileCache->GetBufferSize()) {
620 f->SetCacheRead(nullptr,fFromTree);
621 delete fFileCache;
622 fFileCache = nullptr;
623 }
624 }
625 // Note if the TFile cache is needed, it will be created at the
626 // beginning of Exec.
627}
628
629////////////////////////////////////////////////////////////////////////////////
630/// Sort the basket according to the user request.
631
633{
634 // Currently this sort __has to__ preserve the order
635 // of basket for each individual branch.
636
637 switch (fCloneMethod) {
639 // nothing to do, it is already sorted.
640 break;
641 case kSortBasketsByEntry: {
642 for(UInt_t i = 0; i < fMaxBaskets; ++i) { fBasketIndex[i] = i; }
644 break;
645 }
647 default: {
648 for(UInt_t i = 0; i < fMaxBaskets; ++i) { fBasketIndex[i] = i; }
650 break;
651 }
652 }
653}
654
655////////////////////////////////////////////////////////////////////////////////
656/// Fill the file cache with the next set of basket.
657///
658/// \param from index of the first lement of fFromBranches to start caching
659/// \return The index of first element of fFromBranches that is not in the cache
661{
662 if (!fFileCache) return 0;
663 // Reset the cache
664 fFileCache->Prefetch(0, 0);
665 Long64_t size = 0;
666 for (UInt_t j = from; j < fMaxBaskets; ++j) {
668
669
670 Int_t index = fBasketNum[ fBasketIndex[j] ];
671 Long64_t pos = frombr->GetBasketSeek(index);
672 Int_t len = frombr->GetBasketBytes()[index];
673 if (pos && len) {
674 size += len;
675 if (size > fFileCache->GetBufferSize()) {
676 return j;
677 }
678 fFileCache->Prefetch(pos,len);
679 }
680 }
681 return fMaxBaskets;
682}
683
684////////////////////////////////////////////////////////////////////////////////
685/// Transfer the basket from the input file to the output file
686
688{
689 TBasket *basket = new TBasket();
690 for(UInt_t j = 0, notCached = 0; j<fMaxBaskets; ++j) {
693
694 TFile *tofile = to->GetFile(0);
695 TFile *fromfile = from->GetFile(0);
696
697 Int_t index = fBasketNum[ fBasketIndex[j] ];
698
699 Long64_t pos = from->GetBasketSeek(index);
700 if (pos!=0) {
701 if (fFileCache && j >= notCached) {
702 notCached = FillCache(notCached);
703 }
704 if (from->GetBasketBytes()[index] == 0) {
705 from->GetBasketBytes()[index] = basket->ReadBasketBytes(pos, fromfile);
706 }
707 Int_t len = from->GetBasketBytes()[index];
708
709 basket->LoadBasketBuffers(pos,len,fromfile,fFromTree);
711 basket->CopyTo(tofile);
712 to->AddBasket(*basket,kTRUE,fToStartEntries + from->GetBasketEntry()[index]);
713 } else {
714 TBasket *frombasket = from->GetBasket( index );
715 if (frombasket && frombasket->GetNevBuf()>0) {
716 TBasket *tobasket = (TBasket*)frombasket->Clone();
717 tobasket->SetBranch(to);
718 to->AddBasket(*tobasket, kFALSE, fToStartEntries+from->GetBasketEntry()[index]);
720 }
721 }
722 }
723 delete basket;
724}
void Class()
Definition: Class.C:29
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
unsigned short UShort_t
Definition: RtypesCore.h:36
int Int_t
Definition: RtypesCore.h:41
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
long long Long64_t
Definition: RtypesCore.h:69
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
#define gDirectory
Definition: TDirectory.h:223
void Info(const char *location, const char *msgfmt,...)
void Error(const char *location, const char *msgfmt,...)
void Warning(const char *location, const char *msgfmt,...)
char name[80]
Definition: TGX11.cxx:109
#define snprintf
Definition: civetweb.c:1540
Manages buffers for branches of a Tree.
Definition: TBasket.h:34
Long64_t CopyTo(TFile *to)
Copy the basket of this branch onto the file to.
Definition: TBasket.cxx:142
Int_t GetNevBuf() const
Definition: TBasket.h:129
void SetBranch(TBranch *branch)
Definition: TBasket.h:148
Int_t LoadBasketBuffers(Long64_t pos, Int_t len, TFile *file, TTree *tree=0)
Load basket buffers in memory without unziping.
Definition: TBasket.cxx:241
Int_t ReadBasketBytes(Long64_t pos, TFile *file)
Read basket buffers in memory and cleanup.
Definition: TBasket.cxx:694
A Branch for the case of an array of clone objects.
Definition: TBranchClones.h:29
TBranch * fBranchCount
Branch with clones count.
Definition: TBranchClones.h:37
A Branch for the case of an object.
Int_t fMaximum
Maximum entries for a TClonesArray or variable array.
A TTree is a list of TBranches.
Definition: TBranch.h:91
virtual Long64_t GetBasketSeek(Int_t basket) const
Return address of basket in the file.
Definition: TBranch.cxx:1278
Int_t GetWriteBasket() const
Definition: TBranch.h:236
@ kDoNotUseBufferMap
Definition: TBranch.h:110
TObjArray * GetListOfBranches()
Definition: TBranch.h:244
virtual void AddBasket(TBasket &b, Bool_t ondisk, Long64_t startEntry)
Add the basket to this branch.
Definition: TBranch.cxx:533
virtual void AddLastBasket(Long64_t startEntry)
Add the start entry of the write basket (not yet created)
Definition: TBranch.cxx:599
TBasket * GetBasket(Int_t basket)
Definition: TBranch.h:211
TObjArray * GetListOfBaskets()
Definition: TBranch.h:243
Long64_t GetEntries() const
Definition: TBranch.h:249
Int_t * GetBasketBytes() const
Definition: TBranch.h:212
virtual TFile * GetFile(Int_t mode=0)
Return pointer to the file where branch buffers reside, returns 0 in case branch buffers reside in th...
Definition: TBranch.cxx:1726
Int_t FlushOneBasket(UInt_t which)
If we have a write basket in memory and it contains some entries and has not yet been written to disk...
Definition: TBranch.cxx:1158
TObjArray * GetListOfLeaves()
Definition: TBranch.h:245
virtual void SetEntries(Long64_t entries)
Set the number of entries in this branch.
Definition: TBranch.cxx:2675
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1979
Long64_t * GetBasketEntry() const
Definition: TBranch.h:213
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition: TClass.cxx:4440
ROOT::NewFunc_t GetNew() const
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5662
TVirtualStreamerInfo * FindStreamerInfo(TObjArray *arr, UInt_t checksum) const
Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum.
Definition: TClass.cxx:6760
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2906
Bool_t cd(const char *path=nullptr) override
Change current directory to "this" directory.
TList * GetListOfKeys() const override
Small helper to keep current directory context.
Definition: TDirectory.h:41
Describe directory structure in memory.
Definition: TDirectory.h:34
virtual TFile * GetFile() const
Definition: TDirectory.h:157
virtual Bool_t IsWritable() const
Definition: TDirectory.h:173
virtual Bool_t cd(const char *path=nullptr)
Change current directory to "this" directory.
Definition: TDirectory.cxx:497
A cache when reading files over the network.
virtual void Prefetch(Long64_t pos, Int_t len)
Add block of length len at position pos in the list of blocks to be prefetched.
virtual Int_t GetBufferSize() const
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:48
virtual Int_t GetNProcessIDs() const
Definition: TFile.h:226
virtual void IncrementProcessIDs()
Definition: TFile.h:244
TObjArray * GetListOfProcessIDs() const
Definition: TFile.h:223
virtual TList * GetStreamerInfoList() final
Read the list of TStreamerInfo objects written to this file.
Definition: TFile.cxx:1338
@ kHasReferences
Definition: TFile.h:179
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition: TKey.h:24
virtual void IncrementPidOffset(UShort_t offset)
Increment fPidOffset by 'offset'.
Definition: TKey.cxx:641
virtual const char * GetClassName() const
Definition: TKey.h:72
virtual void * ReadObjectAny(const TClass *expectedClass)
To read an object (non deriving from TObject) from the file.
Definition: TKey.cxx:994
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:49
virtual const char * GetTypeName() const
Definition: TLeaf.h:130
virtual Bool_t IncludeRange(TLeaf *)
Definition: TLeaf.h:137
A doubly linked list.
Definition: TList.h:44
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TNamed.cxx:74
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
An array of TObjects.
Definition: TObjArray.h:37
virtual void AddLast(TObject *obj)
Add object in the next empty slot in the array.
Definition: TObjArray.cxx:177
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:234
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:522
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:90
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:785
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
void ResetBit(UInt_t f)
Definition: TObject.h:171
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition: TProcessID.h:69
Int_t IncrementCount()
Increase the reference count to this object.
Definition: TProcessID.cxx:311
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
void ForceWriteInfo(TFile *file, Bool_t force=kFALSE)
Recursively mark streamer infos for writing to a file.
Int_t GetClassVersion() const
UInt_t GetCheckSum() const
Basic string class.
Definition: TString.h:131
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
const char * Data() const
Definition: TString.h:364
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
Bool_t operator()(UInt_t i1, UInt_t i2)
Definition: TTreeCloner.cxx:56
Bool_t operator()(UInt_t i1, UInt_t i2)
Definition: TTreeCloner.cxx:43
TTreeCloner * fObject
Definition: TTreeCloner.h:75
Class implementing or helping the various TTree cloning method.
Definition: TTreeCloner.h:38
friend class CompareEntry
Definition: TTreeCloner.h:89
UInt_t * fBasketBranchNum
[fMaxBaskets] Index of the branch(es) of the basket.
Definition: TTreeCloner.h:51
TObjArray fToBranches
Definition: TTreeCloner.h:48
void ImportClusterRanges()
Set the entries and import the cluster range of the.
UInt_t CollectBranches()
Fill the array of branches, matching the branches of the 'from' and 'to' TTrees Returns the total num...
TTree * fToTree
Definition: TTreeCloner.h:45
UInt_t fOptions
Definition: TTreeCloner.h:43
void CollectBaskets()
Collect the information about the on-file basket that need to be copied.
TObjArray fFromBranches
Definition: TTreeCloner.h:47
UInt_t * fBasketIndex
[fMaxBaskets] ordered list of basket indices to be written.
Definition: TTreeCloner.h:56
UInt_t FillCache(UInt_t from)
Fill the file cache with the next set of basket.
Bool_t Exec()
Execute the cloning.
void CopyStreamerInfos()
Make sure that all the needed TStreamerInfo are present in the output file.
void WriteBaskets()
Transfer the basket from the input file to the output file.
@ kIgnoreMissingTopLevel
Definition: TTreeCloner.h:104
Bool_t IsValid()
Definition: TTreeCloner.h:121
@ kSortBasketsByOffset
Definition: TTreeCloner.h:70
@ kSortBasketsByEntry
Definition: TTreeCloner.h:71
@ kSortBasketsByBranch
Definition: TTreeCloner.h:69
Option_t * fMethod
Definition: TTreeCloner.h:46
Long64_t * fBasketSeek
[fMaxBaskets] list of basket position to be read.
Definition: TTreeCloner.h:54
void SetCacheSize(Int_t size)
Set the TFile cache size to be used.
void CopyMemoryBaskets()
Transfer the basket from the input file to the output file.
UShort_t fPidOffset
Offset to be added to the copied key/basket.
Definition: TTreeCloner.h:58
Bool_t fIsValid
Definition: TTreeCloner.h:41
Long64_t * fBasketEntry
[fMaxBaskets] list of basket start entries.
Definition: TTreeCloner.h:55
void CreateCache()
Create a TFileCacheRead if it was requested.
TFileCacheRead * fFileCache
File Cache used to reduce the number of individual reads.
Definition: TTreeCloner.h:64
void CopyProcessIds()
Make sure that all the needed TStreamerInfo are present in the output file.
TTreeCloner(const TTreeCloner &)=delete
TFileCacheRead * fPrevCache
Cache that set before the TTreeCloner ctor for the 'from' TTree if any.
Definition: TTreeCloner.h:65
TTree * fFromTree
Definition: TTreeCloner.h:44
Bool_t fNeedConversion
True if the fast merge is not possible but a slow merge might possible.
Definition: TTreeCloner.h:42
UInt_t fCloneMethod
Indicates which cloning method was selected.
Definition: TTreeCloner.h:60
void RestoreCache()
Restore the TFileCacheRead to its previous value.
TString fWarningMsg
Text of the error message lead to an 'invalid' state.
Definition: TTreeCloner.h:39
void CloseOutWriteBaskets()
Before we can start adding new basket, we need to flush to disk the partially filled baskets (the Wri...
Long64_t fToStartEntries
Number of entries in the target tree before any addition.
Definition: TTreeCloner.h:61
virtual ~TTreeCloner()
TTreeCloner destructor.
UInt_t fMaxBaskets
Definition: TTreeCloner.h:50
Int_t fCacheSize
Requested size of the file cache.
Definition: TTreeCloner.h:63
friend class CompareSeek
Definition: TTreeCloner.h:88
UInt_t * fBasketNum
[fMaxBaskets] index of the basket within the branch.
Definition: TTreeCloner.h:52
void SortBaskets()
Sort the basket according to the user request.
A TTree represents a columnar dataset.
Definition: TTree.h:72
virtual Long64_t SetEntries(Long64_t n=-1)
Change number of entries in the tree.
Definition: TTree.cxx:8748
virtual TBranch * BranchRef()
Build the optional branch supporting the TRefTable.
Definition: TTree.cxx:2292
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition: TTree.cxx:5338
TDirectory * GetDirectory() const
Definition: TTree.h:449
TTreeCache * GetReadCache(TFile *file) const
Find and return the TTreeCache registered with the file and which may contain branches for us.
Definition: TTree.cxx:6174
Long64_t fFlushedBytes
Number of auto-flushed bytes.
Definition: TTree.h:82
virtual TBranchRef * GetBranchRef() const
Definition: TTree.h:437
virtual Long64_t GetEntries() const
Definition: TTree.h:450
Long64_t GetCacheAutoSize(Bool_t withDefault=kFALSE) const
Used for automatic sizing of the cache.
Definition: TTree.cxx:5276
virtual TObjArray * GetListOfBranches()
Definition: TTree.h:475
virtual TTree * GetTree() const
Definition: TTree.h:504
void ImportClusterRanges(TTree *fromtree)
Appends the cluster range information stored in 'fromtree' to this tree, including the value of fAuto...
Definition: TTree.cxx:6228
auto * l
Definition: textangle.C:4