ROOT  6.06/09
Reference Guide
TBranch.cxx
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Rene Brun 12/01/96
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 #include "TBranch.h"
13 
14 #include "Compression.h"
15 #include "TBasket.h"
16 #include "TBranchBrowsable.h"
17 #include "TBrowser.h"
18 #include "TClass.h"
19 #include "TBufferFile.h"
20 #include "TClonesArray.h"
21 #include "TFile.h"
22 #include "TLeaf.h"
23 #include "TLeafB.h"
24 #include "TLeafC.h"
25 #include "TLeafD.h"
26 #include "TLeafF.h"
27 #include "TLeafI.h"
28 #include "TLeafL.h"
29 #include "TLeafO.h"
30 #include "TLeafObject.h"
31 #include "TLeafS.h"
32 #include "TMessage.h"
33 #include "TROOT.h"
34 #include "TSystem.h"
35 #include "TMath.h"
36 #include "TTree.h"
37 #include "TTreeCache.h"
38 #include "TTreeCacheUnzip.h"
39 #include "TVirtualMutex.h"
40 #include "TVirtualPad.h"
41 
42 #include <atomic>
43 #include <cstddef>
44 #include <string.h>
45 #include <stdio.h>
46 
48 
49 #if (__GNUC__ >= 3) || defined(__INTEL_COMPILER)
50 #if !defined(R__unlikely)
51  #define R__unlikely(expr) __builtin_expect(!!(expr), 0)
52 #endif
53 #if !defined(R__likely)
54  #define R__likely(expr) __builtin_expect(!!(expr), 1)
55 #endif
56 #else
57  #define R__unlikely(expr) expr
58  #define R__likely(expr) expr
59 #endif
60 
61 /** \class TBranch
62 A TTree is a list of TBranches
63 
64 A TBranch supports:
65  - The list of TLeaf describing this branch.
66  - The list of TBasket (branch buffers).
67 
68 See TBranch structure in TTree.
69 
70 See also specialized branches:
71  - TBranchObject in case the branch is one object
72  - TBranchClones in case the branch is an array of clone objects
73 */
74 
76 
77 ////////////////////////////////////////////////////////////////////////////////
78 /// Default constructor. Used for I/O by default.
79 
81 : TNamed()
82 , TAttFill(0, 1001)
83 , fCompress(0)
84 , fBasketSize(32000)
85 , fEntryOffsetLen(1000)
86 , fWriteBasket(0)
87 , fEntryNumber(0)
88 , fOffset(0)
89 , fMaxBaskets(10)
90 , fNBaskets(0)
91 , fSplitLevel(0)
92 , fNleaves(0)
93 , fReadBasket(0)
94 , fReadEntry(-1)
95 , fFirstBasketEntry(-1)
96 , fNextBasketEntry(-1)
97 , fCurrentBasket(0)
98 , fEntries(0)
99 , fFirstEntry(0)
100 , fTotBytes(0)
101 , fZipBytes(0)
102 , fBranches()
103 , fLeaves()
104 , fBaskets(fMaxBaskets)
105 , fBasketBytes(0)
106 , fBasketEntry(0)
107 , fBasketSeek(0)
108 , fTree(0)
109 , fMother(0)
110 , fParent(0)
111 , fAddress(0)
112 , fDirectory(0)
113 , fFileName("")
114 , fEntryBuffer(0)
115 , fBrowsables(0)
116 , fSkipZip(kFALSE)
117 , fReadLeaves(&TBranch::ReadLeavesImpl)
118 , fFillLeaves(&TBranch::FillLeavesImpl)
119 {
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Create a Branch as a child of a Tree
125 ///
126 /// * address is the address of the first item of a structure
127 /// or the address of a pointer to an object (see example in TTree.cxx).
128 /// * leaflist is the concatenation of all the variable names and types
129 /// separated by a colon character :
130 /// The variable name and the variable type are separated by a
131 /// slash (/). The variable type must be 1 character. (Characters
132 /// after the first are legal and will be appended to the visible
133 /// name of the leaf, but have no effect.) If no type is given, the
134 /// type of the variable is assumed to be the same as the previous
135 /// variable. If the first variable does not have a type, it is
136 /// assumed of type F by default. The list of currently supported
137 /// types is given below:
138 /// - C : a character string terminated by the 0 character
139 /// - B : an 8 bit signed integer (Char_t)
140 /// - b : an 8 bit unsigned integer (UChar_t)
141 /// - S : a 16 bit signed integer (Short_t)
142 /// - s : a 16 bit unsigned integer (UShort_t)
143 /// - I : a 32 bit signed integer (Int_t)
144 /// - i : a 32 bit unsigned integer (UInt_t)
145 /// - F : a 32 bit floating point (Float_t)
146 /// - D : a 64 bit floating point (Double_t)
147 /// - L : a 64 bit signed integer (Long64_t)
148 /// - l : a 64 bit unsigned integer (ULong64_t)
149 /// - O : [the letter 'o', not a zero] a boolean (Bool_t)
150 ///
151 /// Arrays of values are supported with the following syntax:
152 /// - If leaf name has the form var[nelem], where nelem is alphanumeric, then
153 /// if nelem is a leaf name, it is used as the variable size of the array,
154 /// otherwise return 0.
155 /// The leaf referred to by nelem **MUST** be an int (/I),
156 /// - If leaf name has the form var[nelem], where nelem is a non-negative integers, then
157 /// it is used as the fixed size of the array.
158 /// - If leaf name has the form of a multi dimension array (e.g. var[nelem][nelem2])
159 /// where nelem and nelem2 are non-negative integers) then
160 /// it is used as a 2 dimensional array of fixed size.
161 /// - Any of other form is not supported.
162 ///
163 /// Note that the TTree will assume that all the item are contiguous in memory.
164 /// On some platform, this is not always true of the member of a struct or a class,
165 /// due to padding and alignment. Sorting your data member in order of decreasing
166 /// sizeof usually leads to their being contiguous in memory.
167 ///
168 /// * bufsize is the buffer size in bytes for this branch
169 /// The default value is 32000 bytes and should be ok for most cases.
170 /// You can specify a larger value (e.g. 256000) if your Tree is not split
171 /// and each entry is large (Megabytes)
172 /// A small value for bufsize is optimum if you intend to access
173 /// the entries in the Tree randomly and your Tree is in split mode.
174 ///
175 /// See an example of a Branch definition in the TTree constructor.
176 ///
177 /// Note that in case the data type is an object, this branch can contain
178 /// only this object.
179 ///
180 /// Note that this function is invoked by TTree::Branch
181 
182 TBranch::TBranch(TTree *tree, const char* name, void* address, const char* leaflist, Int_t basketsize, Int_t compress)
183 : TNamed(name, leaflist)
184 , TAttFill(0, 1001)
185 , fCompress(compress)
186 , fBasketSize((basketsize < 100) ? 100 : basketsize)
187 , fEntryOffsetLen(0)
188 , fWriteBasket(0)
189 , fEntryNumber(0)
190 , fOffset(0)
191 , fMaxBaskets(10)
192 , fNBaskets(0)
193 , fSplitLevel(0)
194 , fNleaves(0)
195 , fReadBasket(0)
196 , fReadEntry(-1)
197 , fFirstBasketEntry(-1)
198 , fNextBasketEntry(-1)
199 , fCurrentBasket(0)
200 , fEntries(0)
201 , fFirstEntry(0)
202 , fTotBytes(0)
203 , fZipBytes(0)
204 , fBranches()
205 , fLeaves()
206 , fBaskets(fMaxBaskets)
207 , fBasketBytes(0)
208 , fBasketEntry(0)
209 , fBasketSeek(0)
210 , fTree(tree)
211 , fMother(0)
212 , fParent(0)
213 , fAddress((char*) address)
214 , fDirectory(fTree->GetDirectory())
215 , fFileName("")
216 , fEntryBuffer(0)
217 , fBrowsables(0)
218 , fSkipZip(kFALSE)
219 , fReadLeaves(&TBranch::ReadLeavesImpl)
220 , fFillLeaves(&TBranch::FillLeavesImpl)
221 {
222  Init(name,leaflist,compress);
223 }
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// Create a Branch as a child of another Branch
227 ///
228 /// See documentation for
229 /// TBranch::TBranch(TTree *, const char *, void *, const char *, Int_t, Int_t)
230 
231 TBranch::TBranch(TBranch *parent, const char* name, void* address, const char* leaflist, Int_t basketsize, Int_t compress)
232 : TNamed(name, leaflist)
233 , TAttFill(0, 1001)
234 , fCompress(compress)
235 , fBasketSize((basketsize < 100) ? 100 : basketsize)
236 , fEntryOffsetLen(0)
237 , fWriteBasket(0)
238 , fEntryNumber(0)
239 , fOffset(0)
240 , fMaxBaskets(10)
241 , fNBaskets(0)
242 , fSplitLevel(0)
243 , fNleaves(0)
244 , fReadBasket(0)
245 , fReadEntry(-1)
246 , fFirstBasketEntry(-1)
247 , fNextBasketEntry(-1)
248 , fCurrentBasket(0)
249 , fEntries(0)
250 , fFirstEntry(0)
251 , fTotBytes(0)
252 , fZipBytes(0)
253 , fBranches()
254 , fLeaves()
255 , fBaskets(fMaxBaskets)
256 , fBasketBytes(0)
257 , fBasketEntry(0)
258 , fBasketSeek(0)
259 , fTree(parent ? parent->GetTree() : 0)
260 , fMother(parent ? parent->GetMother() : 0)
261 , fParent(parent)
262 , fAddress((char*) address)
263 , fDirectory(fTree ? fTree->GetDirectory() : 0)
264 , fFileName("")
265 , fEntryBuffer(0)
266 , fBrowsables(0)
267 , fSkipZip(kFALSE)
268 , fReadLeaves(&TBranch::ReadLeavesImpl)
269 , fFillLeaves(&TBranch::FillLeavesImpl)
270 {
271  Init(name,leaflist,compress);
272 }
273 
274 void TBranch::Init(const char* name, const char* leaflist, Int_t compress)
275 {
276  // Initialization routine called from the constructor. This should NOT be made virtual.
277 
279  if ((compress == -1) && fTree->GetDirectory()) {
280  TFile* bfile = fTree->GetDirectory()->GetFile();
281  if (bfile) {
282  fCompress = bfile->GetCompressionSettings();
283  }
284  }
285 
289 
290  for (Int_t i = 0; i < fMaxBaskets; ++i) {
291  fBasketBytes[i] = 0;
292  fBasketEntry[i] = 0;
293  fBasketSeek[i] = 0;
294  }
295 
296  //
297  // Decode the leaflist (search for : as separator).
298  //
299 
300  char* nameBegin = const_cast<char*>(leaflist);
301  Int_t offset = 0;
302  // FIXME: Make these string streams instead.
303  char* leafname = new char[640];
304  char* leaftype = new char[320];
305  // Note: The default leaf type is a float.
306  strlcpy(leaftype, "F",320);
307  char* pos = const_cast<char*>(leaflist);
308  const char* leaflistEnd = leaflist + strlen(leaflist);
309  for (; pos <= leaflistEnd; ++pos) {
310  // -- Scan leaf specification and create leaves.
311  if ((*pos == ':') || (*pos == 0)) {
312  // -- Reached end of a leaf spec, create a leaf.
313  Int_t lenName = pos - nameBegin;
314  char* ctype = 0;
315  if (lenName) {
316  strncpy(leafname, nameBegin, lenName);
317  leafname[lenName] = 0;
318  ctype = strstr(leafname, "/");
319  if (ctype) {
320  *ctype = 0;
321  strlcpy(leaftype, ctype + 1,320);
322  }
323  }
324  if (lenName == 0 || ctype == leafname) {
325  Warning("TBranch","No name was given to the leaf number '%d' in the leaflist of the branch '%s'.",fNleaves,name);
326  snprintf(leafname,640,"__noname%d",fNleaves);
327  }
328  TLeaf* leaf = 0;
329  if (*leaftype == 'C') {
330  leaf = new TLeafC(this, leafname, leaftype);
331  } else if (*leaftype == 'O') {
332  leaf = new TLeafO(this, leafname, leaftype);
333  } else if (*leaftype == 'B') {
334  leaf = new TLeafB(this, leafname, leaftype);
335  } else if (*leaftype == 'b') {
336  leaf = new TLeafB(this, leafname, leaftype);
337  leaf->SetUnsigned();
338  } else if (*leaftype == 'S') {
339  leaf = new TLeafS(this, leafname, leaftype);
340  } else if (*leaftype == 's') {
341  leaf = new TLeafS(this, leafname, leaftype);
342  leaf->SetUnsigned();
343  } else if (*leaftype == 'I') {
344  leaf = new TLeafI(this, leafname, leaftype);
345  } else if (*leaftype == 'i') {
346  leaf = new TLeafI(this, leafname, leaftype);
347  leaf->SetUnsigned();
348  } else if (*leaftype == 'F') {
349  leaf = new TLeafF(this, leafname, leaftype);
350  } else if (*leaftype == 'f') {
351  leaf = new TLeafF(this, leafname, leaftype);
352  } else if (*leaftype == 'L') {
353  leaf = new TLeafL(this, leafname, leaftype);
354  } else if (*leaftype == 'l') {
355  leaf = new TLeafL(this, leafname, leaftype);
356  leaf->SetUnsigned();
357  } else if (*leaftype == 'D') {
358  leaf = new TLeafD(this, leafname, leaftype);
359  } else if (*leaftype == 'd') {
360  leaf = new TLeafD(this, leafname, leaftype);
361  }
362  if (!leaf) {
363  Error("TLeaf", "Illegal data type for %s/%s", name, leaflist);
364  delete[] leaftype;
365  delete [] leafname;
366  MakeZombie();
367  return;
368  }
369  if (leaf->IsZombie()) {
370  delete leaf;
371  leaf = 0;
372  Error("TBranch", "Illegal leaf: %s/%s", name, leaflist);
373  delete [] leafname;
374  delete[] leaftype;
375  MakeZombie();
376  return;
377  }
378  leaf->SetBranch(this);
379  leaf->SetAddress((char*) (fAddress + offset));
380  leaf->SetOffset(offset);
381  if (leaf->GetLeafCount()) {
382  // -- Leaf is a varying length array, we need an offset array.
383  fEntryOffsetLen = 1000;
384  }
385  if (leaf->InheritsFrom(TLeafC::Class())) {
386  // -- Leaf is a character string, we need an offset array.
387  fEntryOffsetLen = 1000;
388  }
389  ++fNleaves;
390  fLeaves.Add(leaf);
391  fTree->GetListOfLeaves()->Add(leaf);
392  if (*pos == 0) {
393  // -- We reached the end of the leaf specification.
394  break;
395  }
396  nameBegin = pos + 1;
397  offset += leaf->GetLenType() * leaf->GetLen();
398  }
399  }
400  delete[] leafname;
401  leafname = 0;
402  delete[] leaftype;
403  leaftype = 0;
404 
405 }
406 
407 ////////////////////////////////////////////////////////////////////////////////
408 /// Destructor.
409 
411 {
412  delete fBrowsables;
413  fBrowsables = 0;
414 
415  // Note: We do *not* have ownership of the buffer.
416  fEntryBuffer = 0;
417 
418  delete [] fBasketSeek;
419  fBasketSeek = 0;
420 
421  delete [] fBasketEntry;
422  fBasketEntry = 0;
423 
424  delete [] fBasketBytes;
425  fBasketBytes = 0;
426 
427  fBaskets.Delete();
428  fNBaskets = 0;
429  fCurrentBasket = 0;
430  fFirstBasketEntry = -1;
431  fNextBasketEntry = -1;
432 
433  // Remove our leaves from our tree's list of leaves.
434  if (fTree) {
435  TObjArray* lst = fTree->GetListOfLeaves();
436  if (lst && lst->GetLast()!=-1) {
437  lst->RemoveAll(&fLeaves);
438  }
439  }
440  // And delete our leaves.
441  fLeaves.Delete();
442 
443  fBranches.Delete();
444 
445  // If we are in a directory and that directory is not the same
446  // directory that our tree is in, then try to find an open file
447  // with the name fFileName. If we find one, delete that file.
448  // We are attempting to close any alternate file which we have
449  // been directed to write our baskets to.
450  // FIXME: We make no attempt to check if someone else might be
451  // using this file. This is very user hostile. A violation
452  // of the principle of least surprises.
453  //
454  // Warning. Must use FindObject by name instead of fDirectory->GetFile()
455  // because two branches may point to the same file and the file
456  // may have already been deleted in the previous branch.
457  if (fDirectory && (!fTree || fDirectory != fTree->GetDirectory())) {
458  TString bFileName( GetRealFileName() );
459 
461  TFile* file = (TFile*)gROOT->GetListOfFiles()->FindObject(bFileName);
462  if (file){
463  file->Close();
464  delete file;
465  file = 0;
466  }
467  }
468 
469  fTree = 0;
470  fDirectory = 0;
471 }
472 
473 ////////////////////////////////////////////////////////////////////////////////
474 /// Add the basket to this branch.
475 
476 void TBranch::AddBasket(TBasket& b, Bool_t ondisk, Long64_t startEntry)
477 {
478  // Warning: if the basket are not 'flushed/copied' in the same
479  // order as they were created, this will induce a slow down in
480  // the insert (since we'll need to move all the record that are
481  // entere 'too early').
482  // Warning we also assume that the __current__ write basket is
483  // not present (aka has been removed).
484 
485  TBasket *basket = &b;
486 
487  basket->SetBranch(this);
488 
489  if (fWriteBasket >= fMaxBaskets) {
491  }
492  Int_t where = fWriteBasket;
493 
494  if (where && startEntry < fBasketEntry[where-1]) {
495  // Need to find the right location and move the possible baskets
496 
497  if (!ondisk) {
498  Warning("AddBasket","The assumption that out-of-order basket only comes from disk based ntuple is false.");
499  }
500 
501  if (startEntry < fBasketEntry[0]) {
502  where = 0;
503  } else {
504  for(Int_t i=fWriteBasket-1; i>=0; --i) {
505  if (fBasketEntry[i] < startEntry) {
506  where = i+1;
507  break;
508  } else if (fBasketEntry[i] == startEntry) {
509  Error("AddBasket","An out-of-order basket matches the entry number of an existing basket.");
510  }
511  }
512  }
513 
514  if (where < fWriteBasket) {
515  // We shall move the content of the array
516  for (Int_t j=fWriteBasket; j > where; --j) {
517  fBasketEntry[j] = fBasketEntry[j-1];
518  fBasketBytes[j] = fBasketBytes[j-1];
519  fBasketSeek[j] = fBasketSeek[j-1];
520  }
521  }
522  }
523  fBasketEntry[where] = startEntry;
524 
525  if (ondisk) {
526  fBasketBytes[where] = basket->GetNbytes(); // not for in mem
527  fBasketSeek[where] = basket->GetSeekKey(); // not for in mem
528  fBaskets.AddAtAndExpand(0,fWriteBasket);
529  ++fWriteBasket;
530  } else {
531  ++fNBaskets;
532  fBaskets.AddAtAndExpand(basket,fWriteBasket);
534  }
535 
536  fEntries += basket->GetNevBuf();
537  fEntryNumber += basket->GetNevBuf();
538  if (ondisk) {
539  fTotBytes += basket->GetObjlen() + basket->GetKeylen() ;
540  fZipBytes += basket->GetNbytes();
541  fTree->AddTotBytes(basket->GetObjlen() + basket->GetKeylen());
542  fTree->AddZipBytes(basket->GetNbytes());
543  }
544 }
545 
546 ////////////////////////////////////////////////////////////////////////////////
547 /// Add the start entry of the write basket (not yet created)
548 
550 {
551  if (fWriteBasket >= fMaxBaskets) {
553  }
554  Int_t where = fWriteBasket;
555 
556  if (where && startEntry < fBasketEntry[where-1]) {
557  // Need to find the right location and move the possible baskets
558 
559  Fatal("AddBasket","The last basket must have the highest entry number (%s/%lld/%d).",GetName(),startEntry,fWriteBasket);
560 
561  }
562  fBasketEntry[where] = startEntry;
563  fBaskets.AddAtAndExpand(0,fWriteBasket);
564 }
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// Browser interface.
568 
570 {
571  if (fNleaves > 1) {
572  fLeaves.Browse(b);
573  } else {
574  // Get the name and strip any extra brackets
575  // in order to get the full arrays.
576  TString name = GetName();
577  Int_t pos = name.First('[');
578  if (pos!=kNPOS) name.Remove(pos);
579 
580  GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
581  if (gPad) gPad->Update();
582  }
583 }
584 
585  ///////////////////////////////////////////////////////////////////////////////
586  /// Loop on all branch baskets. If the file where branch buffers reside is
587  /// writable, free the disk space associated to the baskets of the branch,
588  /// then call Reset(). If the option contains "all", delete also the baskets
589  /// for the subbranches.
590  /// The branch is reset.
591  /// NOTE that this function must be used with extreme care. Deleting branch baskets
592  /// fragments the file and may introduce inefficiencies when adding new entries
593  /// in the Tree or later on when reading the Tree.
594 
596 {
597  TString opt = option;
598  opt.ToLower();
599  TFile *file = GetFile(0);
600 
601  if(fDirectory && (fDirectory != gROOT) && fDirectory->IsWritable()) {
602  for(Int_t i=0; i<fWriteBasket; i++) {
603  if (fBasketSeek[i]) file->MakeFree(fBasketSeek[i],fBasketSeek[i]+fBasketBytes[i]-1);
604  }
605  }
606 
607  // process subbranches
608  if (opt.Contains("all")) {
610  Int_t nb = lb->GetEntriesFast();
611  for (Int_t j = 0; j < nb; j++) {
612  TBranch* branch = (TBranch*) lb->UncheckedAt(j);
613  if (branch) branch->DeleteBaskets("all");
614  }
615  }
616  DropBaskets("all");
617  Reset();
618 }
619 
620 ////////////////////////////////////////////////////////////////////////////////
621 /// Loop on all branch baskets. Drop all baskets from memory except readbasket.
622 /// If the option contains "all", drop all baskets including
623 /// read- and write-baskets (unless they are not stored individually on disk).
624 /// The option "all" also lead to DropBaskets being called on the sub-branches.
625 
627 {
628  Bool_t all = kFALSE;
629  if (options && options[0]) {
630  TString opt = options;
631  opt.ToLower();
632  if (opt.Contains("all")) all = kTRUE;
633  }
634 
635  TBasket *basket;
636  Int_t nbaskets = fBaskets.GetEntriesFast();
637 
638  if ( (fNBaskets>1) || all ) {
639  //slow case
640  for (Int_t i=0;i<nbaskets;i++) {
641  basket = (TBasket*)fBaskets.UncheckedAt(i);
642  if (!basket) continue;
643  if ((i == fReadBasket || i == fWriteBasket) && !all) continue;
644  // if the basket is not yet on file but already has event in it
645  // we must continue to avoid dropping the basket (and thus losing data)
646  if (fBasketBytes[i]==0 && basket->GetNevBuf() > 0) continue;
647  basket->DropBuffers();
648  --fNBaskets;
649  fBaskets.RemoveAt(i);
650  if (basket == fCurrentBasket) {
651  fCurrentBasket = 0;
652  fFirstBasketEntry = -1;
653  fNextBasketEntry = -1;
654  }
655  delete basket;
656  }
657 
658  // process subbranches
659  if (all) {
661  Int_t nb = lb->GetEntriesFast();
662  for (Int_t j = 0; j < nb; j++) {
663  TBranch* branch = (TBranch*) lb->UncheckedAt(j);
664  if (!branch) continue;
665  branch->DropBaskets("all");
666  }
667  }
668  } else {
669  //fast case
670  if (nbaskets > 0) {
671  Int_t i = fBaskets.GetLast();
672  basket = (TBasket*)fBaskets.UncheckedAt(i);
673  if (basket && fBasketBytes[i]!=0) {
674  basket->DropBuffers();
675  if (basket == fCurrentBasket) {
676  fCurrentBasket = 0;
677  fFirstBasketEntry = -1;
678  fNextBasketEntry = -1;
679  }
680  delete basket;
681  fBaskets.AddAt(0,i);
682  fBaskets.SetLast(-1);
683  fNBaskets = 0;
684  }
685  }
686  }
687 
688 }
689 
690 ////////////////////////////////////////////////////////////////////////////////
691 /// Increase BasketEntry buffer of a minimum of 10 locations
692 /// and a maximum of 50 per cent of current size.
693 
695 {
696  Int_t newsize = TMath::Max(10,Int_t(1.5*fMaxBaskets));
697  fBasketBytes = TStorage::ReAllocInt(fBasketBytes, newsize, fMaxBaskets);
699  newsize*sizeof(Long64_t),fMaxBaskets*sizeof(Long64_t));
701  newsize*sizeof(Long64_t),fMaxBaskets*sizeof(Long64_t));
702 
703  fMaxBaskets = newsize;
704 
705  fBaskets.Expand(newsize);
706 
707  for (Int_t i=fWriteBasket;i<fMaxBaskets;i++) {
708  fBasketBytes[i] = 0;
709  fBasketEntry[i] = 0;
710  fBasketSeek[i] = 0;
711  }
712 }
713 
714 ////////////////////////////////////////////////////////////////////////////////
715 /// Loop on all leaves of this branch to fill Basket buffer.
716 ///
717 /// The function returns the number of bytes committed to the memory basket.
718 /// If a write error occurs, the number of bytes returned is -1.
719 /// If no data are written, because e.g. the branch is disabled,
720 /// the number of bytes returned is 0.
721 ///
722 
724 {
725  if (TestBit(kDoNotProcess)) {
726  return 0;
727  }
728 
729  TBasket* basket = GetBasket(fWriteBasket);
730  if (!basket) {
731  basket = fTree->CreateBasket(this); // create a new basket
732  if (!basket) return 0;
733  ++fNBaskets;
734  fBaskets.AddAtAndExpand(basket,fWriteBasket);
735  }
736  TBuffer* buf = basket->GetBufferRef();
737 
738  // Fill basket buffer.
739 
740  Int_t nsize = 0;
741 
742  if (buf->IsReading()) {
743  basket->SetWriteMode();
744  }
745 
746  buf->ResetMap();
747 
748  Int_t lnew = 0;
749  Int_t nbytes = 0;
750 
751  if (fEntryBuffer) {
752  nbytes = FillEntryBuffer(basket,buf,lnew);
753  } else {
754  Int_t lold = buf->Length();
755  basket->Update(lold);
756  ++fEntries;
757  ++fEntryNumber;
758  (this->*fFillLeaves)(*buf);
759  if (buf->GetMapCount()) {
760  // The map is used.
762  }
763  lnew = buf->Length();
764  nbytes = lnew - lold;
765  }
766 
767  if (fEntryOffsetLen) {
768  Int_t nevbuf = basket->GetNevBuf();
769  // Total size in bytes of EntryOffset table.
770  nsize = nevbuf * sizeof(Int_t);
771  } else {
772  if (!basket->GetNevBufSize()) {
773  basket->SetNevBufSize(nbytes);
774  }
775  }
776 
777  // Should we create a new basket?
778  // fSkipZip force one entry per buffer (old stuff still maintained for CDF)
779  // Transfer full compressed buffer only
780 
781  if ((fSkipZip && (lnew >= TBuffer::kMinimalSize)) || (buf->TestBit(TBufferFile::kNotDecompressed)) || ((lnew + (2 * nsize) + nbytes) >= fBasketSize)) {
783  return nbytes;
784  }
785  Int_t nout = WriteBasket(basket,fWriteBasket);
786  return (nout >= 0) ? nbytes : -1;
787  }
788  return nbytes;
789 }
790 
791 ////////////////////////////////////////////////////////////////////////////////
792 /// Copy the data from fEntryBuffer into the current basket.
793 
795 {
796  Int_t nbytes = 0;
797  Int_t objectStart = 0;
798  Int_t last = 0;
799  Int_t lold = buf->Length();
800 
801  // Handle the special case of fEntryBuffer != 0
802  if (fEntryBuffer->IsA() == TMessage::Class()) {
803  objectStart = 8;
804  }
806  // The buffer given as input has not been decompressed.
807  if (basket->GetNevBuf()) {
808  // If the basket already contains entry we need to close it
809  // out. (This is because we can only transfer full compressed
810  // buffer)
811  WriteBasket(basket,fWriteBasket);
812  // And restart from scratch
813  return Fill();
814  }
815  Int_t startpos = fEntryBuffer->Length();
817  static TBasket toread_fLast;
819  toread_fLast.Streamer(*fEntryBuffer);
821  last = toread_fLast.GetLast();
822  // last now contains the decompressed number of bytes.
823  fEntryBuffer->SetBufferOffset(startpos);
824  buf->SetBufferOffset(0);
826  basket->Update(lold);
827  } else {
828  // We are required to copy starting at the version number (so not
829  // including the class name.
830  // See if byte count is here, if not it class still be a newClass
831  const UInt_t kNewClassTag = 0xFFFFFFFF;
832  const UInt_t kByteCountMask = 0x40000000; // OR the byte count with this
833  UInt_t tag = 0;
834  UInt_t startpos = fEntryBuffer->Length();
835  fEntryBuffer->SetBufferOffset(objectStart);
836  *fEntryBuffer >> tag;
837  if (tag & kByteCountMask) {
838  *fEntryBuffer >> tag;
839  }
840  if (tag == kNewClassTag) {
841  UInt_t maxsize = 256;
842  char* s = new char[maxsize];
843  Int_t name_start = fEntryBuffer->Length();
844  fEntryBuffer->ReadString(s, maxsize); // Reads at most maxsize - 1 characters, plus null at end.
845  while (strlen(s) == (maxsize - 1)) {
846  // The classname is too large, try again with a large buffer.
847  fEntryBuffer->SetBufferOffset(name_start);
848  maxsize *= 2;
849  delete[] s;
850  s = new char[maxsize];
851  fEntryBuffer->ReadString(s, maxsize); // Reads at most maxsize - 1 characters, plus null at end
852  }
853  } else {
854  fEntryBuffer->SetBufferOffset(objectStart);
855  }
856  objectStart = fEntryBuffer->Length();
857  fEntryBuffer->SetBufferOffset(startpos);
858  basket->Update(lold, objectStart - fEntryBuffer->GetBufferDisplacement());
859  }
860  fEntries++;
861  fEntryNumber++;
862  UInt_t len = 0;
863  UInt_t startpos = fEntryBuffer->Length();
864  if (startpos > UInt_t(objectStart)) {
865  // We assume this buffer have just been directly filled
866  // the current position in the buffer indicates the end of the object!
867  len = fEntryBuffer->Length() - objectStart;
868  } else {
869  // The buffer have been acquired either via TSocket or via
870  // TBuffer::SetBuffer(newloc,newsize)
871  // Only the actual size of the memory buffer gives us an hint about where
872  // the object ends.
873  len = fEntryBuffer->BufferSize() - objectStart;
874  }
875  buf->WriteBuf(fEntryBuffer->Buffer() + objectStart, len);
877  // The original buffer came pre-compressed and thus the buffer Length
878  // does not really show the really object size
879  // lnew = nbytes = basket->GetLast();
880  nbytes = last;
881  lnew = last;
882  } else {
883  lnew = buf->Length();
884  nbytes = lnew - lold;
885  }
886 
887  return nbytes;
888 }
889 
890 ////////////////////////////////////////////////////////////////////////////////
891 /// Find the immediate sub-branch with passed name.
892 
894 {
895  // We allow the user to pass only the last dotted component of the name.
896  std::string longnm;
897  longnm.reserve(fName.Length()+strlen(name)+3);
898  longnm = fName.Data();
899  if (longnm[longnm.length()-1]==']') {
900  std::size_t dim = longnm.find_first_of("[");
901  if (dim != std::string::npos) {
902  longnm.erase(dim);
903  }
904  }
905  if (longnm[longnm.length()-1] != '.') {
906  longnm += '.';
907  }
908  longnm += name;
909  UInt_t namelen = strlen(name);
910 
911  Int_t nbranches = fBranches.GetEntries();
912  TBranch* branch = 0;
913  for(Int_t i = 0; i < nbranches; ++i) {
914  branch = (TBranch*) fBranches.UncheckedAt(i);
915 
916  const char *brname = branch->fName.Data();
917  UInt_t brlen = branch->fName.Length();
918  if (brname[brlen-1]==']') {
919  const char *dim = strchr(brname,'[');
920  if (dim) {
921  brlen = dim - brname;
922  }
923  }
924  if (namelen == brlen /* same effective size */
925  && strncmp(name,brname,brlen) == 0) {
926  return branch;
927  }
928  if (brlen == (size_t)longnm.length()
929  && strncmp(longnm.c_str(),brname,brlen) == 0) {
930  return branch;
931  }
932  }
933  return 0;
934 }
935 
936 ////////////////////////////////////////////////////////////////////////////////
937 /// Find the leaf corresponding to the name 'searchname'.
938 
939 TLeaf* TBranch::FindLeaf(const char* searchname)
940 {
941  TString leafname;
942  TString leaftitle;
943  TString longname;
944  TString longtitle;
945 
946  // We allow the user to pass only the last dotted component of the name.
948  TLeaf* leaf = 0;
949  while ((leaf = (TLeaf*) next())) {
950  leafname = leaf->GetName();
951  Ssiz_t dim = leafname.First('[');
952  if (dim >= 0) leafname.Remove(dim);
953 
954  if (leafname == searchname) return leaf;
955 
956  // The leaf element contains the branch name in its name, let's use the title.
957  leaftitle = leaf->GetTitle();
958  dim = leaftitle.First('[');
959  if (dim >= 0) leaftitle.Remove(dim);
960 
961  if (leaftitle == searchname) return leaf;
962 
963  TBranch* branch = leaf->GetBranch();
964  if (branch) {
965  longname.Form("%s.%s",branch->GetName(),leafname.Data());
966  dim = longname.First('[');
967  if (dim>=0) longname.Remove(dim);
968  if (longname == searchname) return leaf;
969 
970  // The leaf element contains the branch name in its name.
971  longname.Form("%s.%s",branch->GetName(),searchname);
972  if (longname==leafname) return leaf;
973 
974  longtitle.Form("%s.%s",branch->GetName(),leaftitle.Data());
975  dim = longtitle.First('[');
976  if (dim>=0) longtitle.Remove(dim);
977  if (longtitle == searchname) return leaf;
978 
979  // The following is for the case where the branch is only
980  // a sub-branch. Since we do not see it through
981  // TTree::GetListOfBranches, we need to see it indirectly.
982  // This is the less sturdy part of this search ... it may
983  // need refining ...
984  if (strstr(searchname, ".") && !strcmp(searchname, branch->GetName())) return leaf;
985  }
986  }
987  return 0;
988 }
989 
990 ////////////////////////////////////////////////////////////////////////////////
991 /// Flush to disk all the baskets of this branch and any of subbranches.
992 /// Return the number of bytes written or -1 in case of write error.
993 
995 {
996  UInt_t nerror = 0;
997  Int_t nbytes = 0;
998 
999  Int_t maxbasket = fWriteBasket + 1;
1000  // The following protection is not necessary since we should always
1001  // have fWriteBasket < fBasket.GetSize()
1002  //if (fBaskets.GetSize() < maxbasket) {
1003  // maxbasket = fBaskets.GetSize();
1004  //}
1005  for(Int_t i=0; i != maxbasket; ++i) {
1006  if (fBaskets.UncheckedAt(i)) {
1007  Int_t nwrite = FlushOneBasket(i);
1008  if (nwrite<0) {
1009  ++nerror;
1010  } else {
1011  nbytes += nwrite;
1012  }
1013  }
1014  }
1015  Int_t len = fBranches.GetEntriesFast();
1016  for (Int_t i = 0; i < len; ++i) {
1017  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
1018  if (!branch) {
1019  continue;
1020  }
1021  Int_t nwrite = branch->FlushBaskets();
1022  if (nwrite<0) {
1023  ++nerror;
1024  } else {
1025  nbytes += nwrite;
1026  }
1027  }
1028  if (nerror) {
1029  return -1;
1030  } else {
1031  return nbytes;
1032  }
1033 }
1034 
1035 ////////////////////////////////////////////////////////////////////////////////
1036 /// If we have a write basket in memory and it contains some entries and
1037 /// has not yet been written to disk, we write it and delete it from memory.
1038 /// Return the number of bytes written;
1039 
1041 {
1042  Int_t nbytes = 0;
1043  if (fDirectory && fBaskets.GetEntries()) {
1044  TBasket *basket = (TBasket*)fBaskets.UncheckedAt(ibasket);
1045 
1046  if (basket) {
1047  if (basket->GetNevBuf()
1048  && fBasketSeek[ibasket]==0) {
1049  // If the basket already contains entry we need to close it out.
1050  // (This is because we can only transfer full compressed buffer)
1051 
1052  if (basket->GetBufferRef()->IsReading()) {
1053  basket->SetWriteMode();
1054  }
1055  nbytes = WriteBasket(basket,ibasket);
1056 
1057  } else {
1058  // If the basket is empty or has already been written.
1059  if ((Int_t)ibasket==fWriteBasket) {
1060  // Nothing to do.
1061  } else {
1062  basket->DropBuffers();
1063  if (basket == fCurrentBasket) {
1064  fCurrentBasket = 0;
1065  fFirstBasketEntry = -1;
1066  fNextBasketEntry = -1;
1067  }
1068  delete basket;
1069  --fNBaskets;
1070  fBaskets[ibasket] = 0;
1071  }
1072  }
1073  }
1074  }
1075  return nbytes;
1076 }
1077 
1078 ////////////////////////////////////////////////////////////////////////////////
1079 /// Return pointer to basket basketnumber in this Branch
1080 
1082 {
1083  // This counter in the sequential case collects errors coming also from
1084  // different files (suppose to have a program reading f1.root, f2.root ...)
1085  // In the mt case, it is made atomic: it safely collects errors from
1086  // different files processed simultaneously.
1087  static std::atomic<Int_t> nerrors(0);
1088 
1089  // reference to an existing basket in memory ?
1090  if (basketnumber <0 || basketnumber > fWriteBasket) return 0;
1091  TBasket *basket = (TBasket*)fBaskets.UncheckedAt(basketnumber);
1092  if (basket) return basket;
1093  if (basketnumber == fWriteBasket) return 0;
1094 
1095  // create/decode basket parameters from buffer
1096  TFile *file = GetFile(0);
1097  if (file == 0) {
1098  return 0;
1099  }
1100  basket = GetFreshBasket();
1101 
1102  // fSkipZip is old stuff still maintained for CDF
1104  if (fBasketBytes[basketnumber] == 0) {
1105  fBasketBytes[basketnumber] = basket->ReadBasketBytes(fBasketSeek[basketnumber],file);
1106  }
1107  //add branch to cache (if any)
1108  TFileCacheRead *pf = file->GetCacheRead(fTree);
1109  if (pf){
1110  if (pf->IsLearning()) pf->AddBranch(this);
1111  if (fSkipZip) pf->SetSkipZip();
1112  }
1113 
1114  //now read basket
1115  Int_t badread = basket->ReadBasketBuffers(fBasketSeek[basketnumber],fBasketBytes[basketnumber],file);
1116  if (badread || basket->GetSeekKey() != fBasketSeek[basketnumber]) {
1117  nerrors++;
1118  if (nerrors > 10) return 0;
1119  if (nerrors == 10) {
1120  printf(" file probably overwritten: stopping reporting error messages\n");
1121  if (fBasketSeek[basketnumber] > 2000000000) {
1122  printf("===>File is more than 2 Gigabytes\n");
1123  return 0;
1124  }
1125  if (fBasketSeek[basketnumber] > 1000000000) {
1126  printf("===>Your file is may be bigger than the maximum file size allowed on your system\n");
1127  printf(" Check your AFS maximum file size limit for example\n");
1128  return 0;
1129  }
1130  }
1131  Error("GetBasket","File: %s at byte:%lld, branch:%s, entry:%lld, badread=%d, nerrors=%d, basketnumber=%d",file->GetName(),basket->GetSeekKey(),GetName(),fReadEntry,badread,nerrors.load(),basketnumber);
1132  return 0;
1133  }
1134 
1135  ++fNBaskets;
1136  fBaskets.AddAt(basket,basketnumber);
1137  return basket;
1138 }
1139 
1140 ////////////////////////////////////////////////////////////////////////////////
1141 /// Return address of basket in the file
1142 
1144 {
1145  if (basketnumber <0 || basketnumber > fWriteBasket) return 0;
1146  return fBasketSeek[basketnumber];
1147 }
1148 
1149 ////////////////////////////////////////////////////////////////////////////////
1150 /// Returns (and, if 0, creates) browsable objects for this branch
1151 /// See TVirtualBranchBrowsable::FillListOfBrowsables.
1152 
1154  if (fBrowsables) return fBrowsables;
1155  fBrowsables=new TList();
1157  return fBrowsables;
1158 }
1159 
1160 ////////////////////////////////////////////////////////////////////////////////
1161 /// Return the name of the user class whose content is stored in this branch,
1162 /// if any. If this branch was created using the 'leaflist' technique, this
1163 /// function returns an empty string.
1164 
1165 const char * TBranch::GetClassName() const
1166 {
1167  return "";
1168 }
1169 
1170 ////////////////////////////////////////////////////////////////////////////////
1171 /// Return icon name depending on type of branch.
1172 
1173 const char* TBranch::GetIconName() const
1174 {
1175  if (IsFolder())
1176  return "TBranchElement-folder";
1177  else
1178  return "TBranchElement-leaf";
1179 }
1180 
1181 ////////////////////////////////////////////////////////////////////////////////
1182 /// Read all leaves of entry and return total number of bytes read.
1183 ///
1184 /// The input argument "entry" is the entry number in the current tree.
1185 /// In case of a TChain, the entry number in the current Tree must be found
1186 /// before calling this function. For example:
1187 ///~~~ {.cpp}
1188 /// TChain* chain = ...;
1189 /// Long64_t localEntry = chain->LoadTree(entry);
1190 /// branch->GetEntry(localEntry);
1191 ///~~~
1192 /// The function returns the number of bytes read from the input buffer.
1193 /// If entry does not exist, the function returns 0.
1194 /// If an I/O error occurs, the function returns -1.
1195 ///
1196 /// See IMPORTANT REMARKS in TTree::GetEntry.
1197 
1199 {
1200  // Remember which entry we are reading.
1201  fReadEntry = entry;
1202 
1203  Bool_t enabled = !TestBit(kDoNotProcess) || getall;
1204  TBasket *basket; // will be initialized in the if/then clauses.
1205  Long64_t first;
1206  if (R__likely(enabled && fFirstBasketEntry <= entry && entry < fNextBasketEntry)) {
1207  // We have found the basket containing this entry.
1208  // make sure basket buffers are in memory.
1209  basket = fCurrentBasket;
1210  first = fFirstBasketEntry;
1211  } else {
1212  if (!enabled) {
1213  return 0;
1214  }
1215  if ((entry < fFirstEntry) || (entry >= fEntryNumber)) {
1216  return 0;
1217  }
1218  first = fFirstBasketEntry;
1219  Long64_t last = fNextBasketEntry - 1;
1220  // Are we still in the same ReadBasket?
1221  if ((entry < first) || (entry > last)) {
1222  fReadBasket = TMath::BinarySearch(fWriteBasket + 1, fBasketEntry, entry);
1223  if (fReadBasket < 0) {
1224  fNextBasketEntry = -1;
1225  Error("In the branch %s, no basket contains the entry %d\n", GetName(), entry);
1226  return -1;
1227  }
1228  if (fReadBasket == fWriteBasket) {
1230  } else {
1232  }
1234  }
1235  // We have found the basket containing this entry.
1236  // make sure basket buffers are in memory.
1237  basket = (TBasket*) fBaskets.UncheckedAt(fReadBasket);
1238  if (!basket) {
1239  basket = GetBasket(fReadBasket);
1240  if (!basket) {
1241  fCurrentBasket = 0;
1242  fFirstBasketEntry = -1;
1243  fNextBasketEntry = -1;
1244  return -1;
1245  }
1246  }
1247  fCurrentBasket = basket;
1248  }
1249  basket->PrepareBasket(entry);
1250  TBuffer* buf = basket->GetBufferRef();
1251 
1252  // This test necessary to read very old Root files (NvE).
1253  if (R__unlikely(!buf)) {
1254  TFile* file = GetFile(0);
1255  if (!file) return -1;
1256  basket->ReadBasketBuffers(fBasketSeek[fReadBasket], fBasketBytes[fReadBasket], file);
1257  buf = basket->GetBufferRef();
1258  }
1259  // Set entry offset in buffer.
1260  if (!TestBit(kDoNotUseBufferMap)) {
1261  buf->ResetMap();
1262  }
1263  if (R__unlikely(!buf->IsReading())) {
1264  basket->SetReadMode();
1265  }
1266  Int_t* entryOffset = basket->GetEntryOffset();
1267  Int_t bufbegin = 0;
1268  if (entryOffset) {
1269  bufbegin = entryOffset[entry-first];
1270  buf->SetBufferOffset(bufbegin);
1271  Int_t* displacement = basket->GetDisplacement();
1272  if (R__unlikely(displacement)) {
1273  buf->SetBufferDisplacement(displacement[entry-first]);
1274  }
1275  } else {
1276  bufbegin = basket->GetKeylen() + ((entry-first) * basket->GetNevBufSize());
1277  buf->SetBufferOffset(bufbegin);
1278  }
1279 
1280  // Int_t bufbegin = buf->Length();
1281  (this->*fReadLeaves)(*buf);
1282  return buf->Length() - bufbegin;
1283 }
1284 
1285 ////////////////////////////////////////////////////////////////////////////////
1286 /// Read all leaves of an entry and export buffers to real objects in a TClonesArray list.
1287 ///
1288 /// Returns total number of bytes read.
1289 
1291 {
1292  // Remember which entry we are reading.
1293  fReadEntry = entry;
1294 
1295  if (TestBit(kDoNotProcess)) {
1296  return 0;
1297  }
1298  if ((entry < 0) || (entry >= fEntryNumber)) {
1299  return 0;
1300  }
1301  Int_t nbytes = 0;
1302  Long64_t first = fFirstBasketEntry;
1303  Long64_t last = fNextBasketEntry - 1;
1304  // Are we still in the same ReadBasket?
1305  if ((entry < first) || (entry > last)) {
1306  fReadBasket = TMath::BinarySearch(fWriteBasket + 1, fBasketEntry, entry);
1307  if (fReadBasket < 0) {
1308  fNextBasketEntry = -1;
1309  Error("In the branch %s, no basket contains the entry %d\n", GetName(), entry);
1310  return -1;
1311  }
1312  if (fReadBasket == fWriteBasket) {
1314  } else {
1316  }
1318  }
1319 
1320  // We have found the basket containing this entry.
1321  // Make sure basket buffers are in memory.
1322  TBasket* basket = GetBasket(fReadBasket);
1323  fCurrentBasket = basket;
1324  if (!basket) {
1325  fFirstBasketEntry = -1;
1326  fNextBasketEntry = -1;
1327  return 0;
1328  }
1329  TBuffer* buf = basket->GetBufferRef();
1330  // Set entry offset in buffer and read data from all leaves.
1331  if (!TestBit(kDoNotUseBufferMap)) {
1332  buf->ResetMap();
1333  }
1334  if (R__unlikely(!buf->IsReading())) {
1335  basket->SetReadMode();
1336  }
1337  Int_t* entryOffset = basket->GetEntryOffset();
1338  Int_t bufbegin = 0;
1339  if (entryOffset) {
1340  bufbegin = entryOffset[entry-first];
1341  buf->SetBufferOffset(bufbegin);
1342  Int_t* displacement = basket->GetDisplacement();
1343  if (R__unlikely(displacement)) {
1344  buf->SetBufferDisplacement(displacement[entry-first]);
1345  }
1346  } else {
1347  bufbegin = basket->GetKeylen() + ((entry-first) * basket->GetNevBufSize());
1348  buf->SetBufferOffset(bufbegin);
1349  }
1350  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(0);
1351  leaf->ReadBasketExport(*buf, li, nentries);
1352  nbytes = buf->Length() - bufbegin;
1353  return nbytes;
1354 }
1355 
1356 ////////////////////////////////////////////////////////////////////////////////
1357 /// Fill expectedClass and expectedType with information on the data type of the
1358 /// object/values contained in this branch (and thus the type of pointers
1359 /// expected to be passed to Set[Branch]Address
1360 /// return 0 in case of success and > 0 in case of failure.
1361 
1362 Int_t TBranch::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
1363 {
1364  expectedClass = 0;
1365  expectedType = kOther_t;
1366  TLeaf* l = (TLeaf*) GetListOfLeaves()->At(0);
1367  if (l) {
1368  expectedType = (EDataType) gROOT->GetType(l->GetTypeName())->GetType();
1369  return 0;
1370  } else {
1371  Error("GetExpectedType", "Did not find any leaves in %s",GetName());
1372  return 1;
1373  }
1374 }
1375 
1376 ////////////////////////////////////////////////////////////////////////////////
1377 /// Return pointer to the file where branch buffers reside, returns 0
1378 /// in case branch buffers reside in the same file as tree header.
1379 /// If mode is 1 the branch buffer file is recreated.
1380 
1382 {
1383  if (fDirectory) return fDirectory->GetFile();
1384 
1385  // check if a file with this name is in the list of Root files
1386  TFile *file = 0;
1387  {
1389  file = (TFile*)gROOT->GetListOfFiles()->FindObject(fFileName.Data());
1390  if (file) {
1391  fDirectory = file;
1392  return file;
1393  }
1394  }
1395 
1396  if (fFileName.Length() == 0) return 0;
1397 
1398  TString bFileName( GetRealFileName() );
1399 
1400  // Open file (new file if mode = 1)
1401  {
1402  TDirectory::TContext ctxt;
1403  if (mode) file = TFile::Open(bFileName, "recreate");
1404  else file = TFile::Open(bFileName);
1405  }
1406  if (!file) return 0;
1407  if (file->IsZombie()) {delete file; return 0;}
1408  fDirectory = (TDirectory*)file;
1409  return file;
1410 }
1411 
1412 ////////////////////////////////////////////////////////////////////////////////
1413 /// Return a fresh basket by either resusing an existing basket that needs
1414 /// to be drop (according to TTree::MemoryFull) or create a new one.
1415 
1417 {
1418  TBasket *basket = 0;
1419  if (GetTree()->MemoryFull(0)) {
1420  if (fNBaskets==1) {
1421  // Steal the existing basket
1422  Int_t oldindex = fBaskets.GetLast();
1423  basket = (TBasket*)fBaskets.UncheckedAt(oldindex);
1424  if (!basket) {
1425  fBaskets.SetLast(-2); // For recalculation of Last.
1426  oldindex = fBaskets.GetLast();
1427  basket = (TBasket*)fBaskets.UncheckedAt(oldindex);
1428  }
1429  if (basket && fBasketBytes[oldindex]!=0) {
1430  if (basket == fCurrentBasket) {
1431  fCurrentBasket = 0;
1432  fFirstBasketEntry = -1;
1433  fNextBasketEntry = -1;
1434  }
1435  fBaskets.AddAt(0,oldindex);
1436  fBaskets.SetLast(-1);
1437  fNBaskets = 0;
1438  } else {
1439  basket = fTree->CreateBasket(this);
1440  }
1441  } else if (fNBaskets == 0) {
1442  // There is nothing to drop!
1443  basket = fTree->CreateBasket(this);
1444  } else {
1445  // Memory is full and there is more than one basket,
1446  // Let DropBaskets do it job.
1447  DropBaskets();
1448  basket = fTree->CreateBasket(this);
1449  }
1450  } else {
1451  basket = fTree->CreateBasket(this);
1452  }
1453  return basket;
1454 }
1455 
1456 ////////////////////////////////////////////////////////////////////////////////
1457 /// Return pointer to the 1st Leaf named name in thisBranch
1458 
1459 TLeaf* TBranch::GetLeaf(const char* name) const
1460 {
1461  Int_t i;
1462  for (i=0;i<fNleaves;i++) {
1463  TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
1464  if (!strcmp(leaf->GetName(),name)) return leaf;
1465  }
1466  return 0;
1467 }
1468 
1469 ////////////////////////////////////////////////////////////////////////////////
1470 /// Get real file name
1471 
1473 {
1474  if (fFileName.Length()==0) {
1475  return fFileName;
1476  }
1477  TString bFileName = fFileName;
1478 
1479  // check if branch file name is absolute or a URL (e.g. /castor/...,
1480  // root://host/..., rfio:/path/...)
1481  char *bname = gSystem->ExpandPathName(fFileName.Data());
1482  if (!gSystem->IsAbsoluteFileName(bname) && !strstr(bname, ":/") && fTree && fTree->GetCurrentFile()) {
1483 
1484  // if not, get filename where tree header is stored
1485  const char *tfn = fTree->GetCurrentFile()->GetName();
1486 
1487  // If it is an archive file we need a special treatment
1488  TUrl arc(tfn);
1489  if (strlen(arc.GetAnchor()) > 0) {
1491  bFileName = arc.GetUrl();
1492  } else {
1493  // if this is an absolute path or a URL then prepend this path
1494  // to the branch file name
1495  char *tname = gSystem->ExpandPathName(tfn);
1496  if (gSystem->IsAbsoluteFileName(tname) || strstr(tname, ":/")) {
1497  bFileName = gSystem->DirName(tname);
1498  bFileName += "/";
1499  bFileName += fFileName;
1500  }
1501  delete [] tname;
1502  }
1503  }
1504  delete [] bname;
1505 
1506  return bFileName;
1507 }
1508 
1509 ////////////////////////////////////////////////////////////////////////////////
1510 /// Return all elements of one row unpacked in internal array fValues
1511 /// [Actually just returns 1 (?)]
1512 
1514 {
1515  return 1;
1516 }
1517 
1518 ////////////////////////////////////////////////////////////////////////////////
1519 /// Return whether this branch is in a mode where the object are decomposed
1520 /// or not (Also known as MakeClass mode).
1521 
1523 {
1524  // Regular TBranch and TBrancObject can not be in makeClass mode
1525 
1526  return kFALSE;
1527 }
1528 
1529 ////////////////////////////////////////////////////////////////////////////////
1530 /// Get our top-level parent branch in the tree.
1531 
1533 {
1534  if (fMother) return fMother;
1535 
1536  const TObjArray* array = fTree->GetListOfBranches();
1537  Int_t n = array->GetEntriesFast();
1538  for (Int_t i = 0; i < n; ++i) {
1539  TBranch* branch = (TBranch*) array->UncheckedAt(i);
1540  TBranch* parent = branch->GetSubBranch(this);
1541  if (parent) {
1542  const_cast<TBranch*>(this)->fMother = branch; // We can not yet use the 'mutable' keyword
1543  return branch;
1544  }
1545  }
1546  return 0;
1547 }
1548 
1549 ////////////////////////////////////////////////////////////////////////////////
1550 /// Find the parent branch of child.
1551 /// Return 0 if child is not in this branch hierarchy.
1552 
1554 {
1555  // Handle error condition, if the parameter is us, we cannot find the parent.
1556  if (this == child) {
1557  // Note: We cast away any const-ness of "this".
1558  return (TBranch*) this;
1559  }
1560 
1561  if (child->fParent) {
1562  return child->fParent;
1563  }
1564 
1565  Int_t len = fBranches.GetEntriesFast();
1566  for (Int_t i = 0; i < len; ++i) {
1567  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
1568  if (!branch) {
1569  continue;
1570  }
1571  if (branch == child) {
1572  // We are the direct parent of child.
1573  const_cast<TBranch*>(child)->fParent = (TBranch*)this; // We can not yet use the 'mutable' keyword
1574  // Note: We cast away any const-ness of "this".
1575  const_cast<TBranch*>(child)->fParent = (TBranch*)this; // We can not yet use the 'mutable' keyword
1576  return (TBranch*) this;
1577  }
1578  // FIXME: This is a tail-recursion!
1579  TBranch* parent = branch->GetSubBranch(child);
1580  if (parent) {
1581  return parent;
1582  }
1583  }
1584  // We failed to find the parent.
1585  return 0;
1586 }
1587 
1588 ////////////////////////////////////////////////////////////////////////////////
1589 /// Return total number of bytes in the branch (including current buffer)
1590 
1592 {
1593  TObjArray &baskets( const_cast<TObjArray&>(fBaskets) );
1594  TBasket *writebasket = 0;
1595  if (fNBaskets == 1) {
1596  writebasket = (TBasket*)fBaskets.UncheckedAt(fWriteBasket);
1597  if (writebasket && writebasket->GetNevBuf()==0) {
1598  baskets[fWriteBasket] = 0;
1599  } else {
1600  writebasket = 0;
1601  }
1602  }
1603  TBufferFile b(TBuffer::kWrite,10000);
1604  TBranch::Class()->WriteBuffer(b,(TBranch*)this);
1605  if (writebasket) {
1606  baskets[fWriteBasket] = writebasket;
1607  }
1608  Long64_t totbytes = 0;
1609  if (fZipBytes > 0) totbytes = fTotBytes;
1610  return totbytes + b.Length();
1611 }
1612 
1613 ////////////////////////////////////////////////////////////////////////////////
1614 /// Return total number of bytes in the branch (excluding current buffer)
1615 /// if option ="*" includes all sub-branches of this branch too
1616 
1618 {
1619  Long64_t totbytes = fTotBytes;
1620  if (!option) return totbytes;
1621  if (option[0] != '*') return totbytes;
1622  //scan sub-branches
1623  Int_t len = fBranches.GetEntriesFast();
1624  for (Int_t i = 0; i < len; ++i) {
1625  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
1626  if (branch) totbytes += branch->GetTotBytes();
1627  }
1628  return totbytes;
1629 }
1630 
1631 ////////////////////////////////////////////////////////////////////////////////
1632 /// Return total number of zip bytes in the branch
1633 /// if option ="*" includes all sub-branches of this branch too
1634 
1636 {
1637  Long64_t zipbytes = fZipBytes;
1638  if (!option) return zipbytes;
1639  if (option[0] != '*') return zipbytes;
1640  //scan sub-branches
1641  Int_t len = fBranches.GetEntriesFast();
1642  for (Int_t i = 0; i < len; ++i) {
1643  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
1644  if (branch) zipbytes += branch->GetZipBytes();
1645  }
1646  return zipbytes;
1647 }
1648 
1649 ////////////////////////////////////////////////////////////////////////////////
1650 /// Return kTRUE if an existing object in a TBranchObject must be deleted.
1651 
1653 {
1654  return TestBit(kAutoDelete);
1655 }
1656 
1657 ////////////////////////////////////////////////////////////////////////////////
1658 /// Return kTRUE if more than one leaf or browsables, kFALSE otherwise.
1659 
1661 {
1662  if (fNleaves > 1) {
1663  return kTRUE;
1664  }
1665  TList* browsables = const_cast<TBranch*>(this)->GetBrowsables();
1666  return browsables && browsables->GetSize();
1667 }
1668 
1669 ////////////////////////////////////////////////////////////////////////////////
1670 /// keep a maximum of fMaxEntries in memory
1671 
1673 {
1674  Int_t dentries = (Int_t) (fEntries - maxEntries);
1675  TBasket* basket = (TBasket*) fBaskets.UncheckedAt(0);
1676  if (basket) basket->MoveEntries(dentries);
1677  fEntries = maxEntries;
1678  fEntryNumber = maxEntries;
1679  //loop on sub branches
1681  for (Int_t i = 0; i < nb; ++i) {
1682  TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
1683  branch->KeepCircular(maxEntries);
1684  }
1685 }
1686 
1687 ////////////////////////////////////////////////////////////////////////////////
1688 /// Baskets associated to this branch are forced to be in memory.
1689 /// You can call TTree::SetMaxVirtualSize(maxmemory) to instruct
1690 /// the system that the total size of the imported baskets does not
1691 /// exceed maxmemory bytes.
1692 /// The function returns the number of baskets that have been put in memory.
1693 /// This method may be called to force all baskets of one or more branches
1694 /// in memory when random access to entries in this branch is required.
1695 /// See also TTree::LoadBaskets to load all baskets of all branches in memory.
1696 
1698 {
1699  Int_t nimported = 0;
1700  Int_t nbaskets = fWriteBasket;
1701  TFile *file = GetFile(0);
1702  if (!file) return 0;
1703  TBasket *basket;
1704  for (Int_t i=0;i<nbaskets;i++) {
1705  basket = (TBasket*)fBaskets.UncheckedAt(i);
1706  if (basket) continue;
1707  basket = GetFreshBasket();
1708  if (fBasketBytes[i] == 0) {
1709  fBasketBytes[i] = basket->ReadBasketBytes(fBasketSeek[i],file);
1710  }
1711  Int_t badread = basket->ReadBasketBuffers(fBasketSeek[i],fBasketBytes[i],file);
1712  if (badread) {
1713  Error("Loadbaskets","Error while reading basket buffer %d of branch %s",i,GetName());
1714  return -1;
1715  }
1716  ++fNBaskets;
1717  fBaskets.AddAt(basket,i);
1718  nimported++;
1719  }
1720  return nimported;
1721 }
1722 
1723 ////////////////////////////////////////////////////////////////////////////////
1724 /// Print TBranch parameters
1725 
1727 {
1728  const int kLINEND = 77;
1729  Float_t cx = 1;
1730 
1731  TString titleContent(GetTitle());
1732  if ( titleContent == GetName() ) {
1733  titleContent.Clear();
1734  }
1735 
1736  if (fLeaves.GetEntries() == 1) {
1737  if (titleContent.Length()>=2 && titleContent[titleContent.Length()-2]=='/' && isalpha(titleContent[titleContent.Length()-1])) {
1738  // The type is already encoded. Nothing to do.
1739  } else {
1740  TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(0);
1741  if (titleContent.Length()) {
1742  titleContent.Prepend(" ");
1743  }
1744  // titleContent.Append("type: ");
1745  titleContent.Prepend(leaf->GetTypeName());
1746  }
1747  }
1748  Int_t titleLength = titleContent.Length();
1749 
1750  Int_t aLength = titleLength + strlen(GetName());
1751  aLength += (aLength / 54 + 1) * 80 + 100;
1752  if (aLength < 200) aLength = 200;
1753  char *bline = new char[aLength];
1754 
1755  Long64_t totBytes = GetTotalSize();
1756  if (fZipBytes) cx = (fTotBytes+0.00001)/fZipBytes;
1757  if (titleLength) snprintf(bline,aLength,"*Br%5d :%-9s : %-54s *",fgCount,GetName(),titleContent.Data());
1758  else snprintf(bline,aLength,"*Br%5d :%-9s : %-54s *",fgCount,GetName()," ");
1759  if (strlen(bline) > UInt_t(kLINEND)) {
1760  char *tmp = new char[strlen(bline)+1];
1761  if (titleLength) strlcpy(tmp, titleContent.Data(),strlen(bline)+1);
1762  snprintf(bline,aLength,"*Br%5d :%-9s : ",fgCount,GetName());
1763  int pos = strlen (bline);
1764  int npos = pos;
1765  int beg=0, end;
1766  while (beg < titleLength) {
1767  for (end=beg+1; end < titleLength-1; end ++)
1768  if (tmp[end] == ':') break;
1769  if (npos + end-beg+1 >= 78) {
1770  while (npos < kLINEND) {
1771  bline[pos ++] = ' ';
1772  npos ++;
1773  }
1774  bline[pos ++] = '*';
1775  bline[pos ++] = '\n';
1776  bline[pos ++] = '*';
1777  npos = 1;
1778  for (; npos < 12; npos ++)
1779  bline[pos ++] = ' ';
1780  bline[pos-2] = '|';
1781  }
1782  for (int n = beg; n <= end; n ++)
1783  bline[pos+n-beg] = tmp[n];
1784  pos += end-beg+1;
1785  npos += end-beg+1;
1786  beg = end+1;
1787  }
1788  while (npos < kLINEND) {
1789  bline[pos ++] = ' ';
1790  npos ++;
1791  }
1792  bline[pos ++] = '*';
1793  bline[pos] = '\0';
1794  delete[] tmp;
1795  }
1796  Printf("%s", bline);
1797  if (fTotBytes > 2000000000) {
1798  Printf("*Entries :%lld : Total Size=%11lld bytes File Size = %lld *",fEntries,totBytes,fZipBytes);
1799  } else {
1800  if (fZipBytes > 0) {
1801  Printf("*Entries :%9lld : Total Size=%11lld bytes File Size = %10lld *",fEntries,totBytes,fZipBytes);
1802  } else {
1803  if (fWriteBasket > 0) {
1804  Printf("*Entries :%9lld : Total Size=%11lld bytes All baskets in memory *",fEntries,totBytes);
1805  } else {
1806  Printf("*Entries :%9lld : Total Size=%11lld bytes One basket in memory *",fEntries,totBytes);
1807  }
1808  }
1809  }
1810  Printf("*Baskets :%9d : Basket Size=%11d bytes Compression= %6.2f *",fWriteBasket,fBasketSize,cx);
1811  Printf("*............................................................................*");
1812  delete [] bline;
1813  fgCount++;
1814 }
1815 
1816 ////////////////////////////////////////////////////////////////////////////////
1817 /// Loop on all leaves of this branch to read Basket buffer.
1818 
1820 {
1821  // fLeaves->ReadBasket(basket);
1822 }
1823 
1824 ////////////////////////////////////////////////////////////////////////////////
1825 /// Loop on all leaves of this branch to read Basket buffer.
1826 
1828 {
1829  for (Int_t i = 0; i < fNleaves; ++i) {
1830  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
1831  leaf->ReadBasket(b);
1832  }
1833 }
1834 
1835 ////////////////////////////////////////////////////////////////////////////////
1836 /// Read zero leaves without the overhead of a loop.
1837 
1839 {
1840 }
1841 
1842 ////////////////////////////////////////////////////////////////////////////////
1843 /// Read one leaf without the overhead of a loop.
1844 
1846 {
1847  ((TLeaf*) fLeaves.UncheckedAt(0))->ReadBasket(b);
1848 }
1849 
1850 ////////////////////////////////////////////////////////////////////////////////
1851 /// Read two leaves without the overhead of a loop.
1852 
1854 {
1855  ((TLeaf*) fLeaves.UncheckedAt(0))->ReadBasket(b);
1856  ((TLeaf*) fLeaves.UncheckedAt(1))->ReadBasket(b);
1857 }
1858 
1859 ////////////////////////////////////////////////////////////////////////////////
1860 /// Loop on all leaves of this branch to fill Basket buffer.
1861 
1863 {
1864  for (Int_t i = 0; i < fNleaves; ++i) {
1865  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
1866  leaf->FillBasket(b);
1867  }
1868 }
1869 
1870 ////////////////////////////////////////////////////////////////////////////////
1871 /// Refresh this branch using new information in b
1872 /// This function is called by TTree::Refresh
1873 
1875 {
1876  if (b==0) return;
1877 
1878  fEntryOffsetLen = b->fEntryOffsetLen;
1879  fWriteBasket = b->fWriteBasket;
1881  fMaxBaskets = b->fMaxBaskets;
1882  fEntries = b->fEntries;
1883  fTotBytes = b->fTotBytes;
1884  fZipBytes = b->fZipBytes;
1885  fReadBasket = 0;
1886  fReadEntry = -1;
1887  fFirstBasketEntry = -1;
1888  fNextBasketEntry = -1;
1889  fCurrentBasket = 0;
1890  delete [] fBasketBytes;
1891  delete [] fBasketEntry;
1892  delete [] fBasketSeek;
1896  Int_t i;
1897  for (i=0;i<fMaxBaskets;i++) {
1898  fBasketBytes[i] = b->fBasketBytes[i];
1899  fBasketEntry[i] = b->fBasketEntry[i];
1900  fBasketSeek[i] = b->fBasketSeek[i];
1901  }
1902  fBaskets.Delete();
1903  Int_t nbaskets = b->fBaskets.GetSize();
1904  fBaskets.Expand(nbaskets);
1905  // If the current fWritebasket is in memory, take it (just swap)
1906  // from the Tree being read
1907  TBasket *basket = (TBasket*)b->fBaskets.UncheckedAt(fWriteBasket);
1908  fBaskets.AddAt(basket,fWriteBasket);
1909  if (basket) {
1910  fNBaskets = 1;
1911  --(b->fNBaskets);
1912  b->fBaskets.RemoveAt(fWriteBasket);
1913  basket->SetBranch(this);
1914  }
1915 }
1916 
1917 ////////////////////////////////////////////////////////////////////////////////
1918 /// Reset a Branch.
1919 ///
1920 /// - Existing buffers are deleted.
1921 /// - Entries, max and min are reset.
1922 
1924 {
1925  fReadBasket = 0;
1926  fReadEntry = -1;
1927  fFirstBasketEntry = -1;
1928  fNextBasketEntry = -1;
1929  fCurrentBasket = 0;
1930  fWriteBasket = 0;
1931  fEntries = 0;
1932  fTotBytes = 0;
1933  fZipBytes = 0;
1934  fEntryNumber = 0;
1935 
1936  if (fBasketBytes) {
1937  for (Int_t i = 0; i < fMaxBaskets; ++i) {
1938  fBasketBytes[i] = 0;
1939  }
1940  }
1941 
1942  if (fBasketEntry) {
1943  for (Int_t i = 0; i < fMaxBaskets; ++i) {
1944  fBasketEntry[i] = 0;
1945  }
1946  }
1947 
1948  if (fBasketSeek) {
1949  for (Int_t i = 0; i < fMaxBaskets; ++i) {
1950  fBasketSeek[i] = 0;
1951  }
1952  }
1953 
1954  fBaskets.Delete();
1955  fNBaskets = 0;
1956 }
1957 
1958 ////////////////////////////////////////////////////////////////////////////////
1959 /// Reset a Branch.
1960 ///
1961 /// - Existing buffers are deleted.
1962 /// - Entries, max and min are reset.
1963 
1965 {
1966  fReadBasket = 0;
1967  fReadEntry = -1;
1968  fFirstBasketEntry = -1;
1969  fNextBasketEntry = -1;
1970  fCurrentBasket = 0;
1971  fWriteBasket = 0;
1972  fEntries = 0;
1973  fTotBytes = 0;
1974  fZipBytes = 0;
1975  fEntryNumber = 0;
1976 
1977  if (fBasketBytes) {
1978  for (Int_t i = 0; i < fMaxBaskets; ++i) {
1979  fBasketBytes[i] = 0;
1980  }
1981  }
1982 
1983  if (fBasketEntry) {
1984  for (Int_t i = 0; i < fMaxBaskets; ++i) {
1985  fBasketEntry[i] = 0;
1986  }
1987  }
1988 
1989  if (fBasketSeek) {
1990  for (Int_t i = 0; i < fMaxBaskets; ++i) {
1991  fBasketSeek[i] = 0;
1992  }
1993  }
1994 
1995  TBasket *reusebasket = (TBasket*)fBaskets[fWriteBasket];
1996  if (reusebasket) {
1997  fBaskets[fWriteBasket] = 0;
1998  } else {
1999  reusebasket = (TBasket*)fBaskets[fReadBasket];
2000  if (reusebasket) {
2001  fBaskets[fReadBasket] = 0;
2002  }
2003  }
2004  fBaskets.Delete();
2005  if (reusebasket) {
2006  fNBaskets = 1;
2007  reusebasket->Reset();
2008  fBaskets[0] = reusebasket;
2009  } else {
2010  fNBaskets = 0;
2011  }
2012 }
2013 
2014 ////////////////////////////////////////////////////////////////////////////////
2015 /// Reset the address of the branch.
2016 
2018 {
2019  fAddress = 0;
2020 
2021  // Reset last read entry number, we have will had new user object now.
2022  fReadEntry = -1;
2023 
2024  for (Int_t i = 0; i < fNleaves; ++i) {
2025  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
2026  leaf->SetAddress(0);
2027  }
2028 
2029  Int_t nbranches = fBranches.GetEntriesFast();
2030  for (Int_t i = 0; i < nbranches; ++i) {
2031  TBranch* abranch = (TBranch*) fBranches[i];
2032  // FIXME: This is a tail recursion.
2033  abranch->ResetAddress();
2034  }
2035 }
2036 
2037 ////////////////////////////////////////////////////////////////////////////////
2038 /// Static function resetting fgCount
2039 
2041 {
2042  fgCount = 0;
2043 }
2044 
2045 ////////////////////////////////////////////////////////////////////////////////
2046 /// Set address of this branch.
2047 
2048 void TBranch::SetAddress(void* addr)
2049 {
2050  if (TestBit(kDoNotProcess)) {
2051  return;
2052  }
2053  fReadEntry = -1;
2054  fFirstBasketEntry = -1;
2055  fNextBasketEntry = -1;
2056  fAddress = (char*) addr;
2057  for (Int_t i = 0; i < fNleaves; ++i) {
2058  TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
2059  Int_t offset = leaf->GetOffset();
2060  if (TestBit(kIsClone)) {
2061  offset = 0;
2062  }
2063  if (fAddress) leaf->SetAddress(fAddress + offset);
2064  else leaf->SetAddress(0);
2065  }
2066 }
2067 
2068 ////////////////////////////////////////////////////////////////////////////////
2069 /// Set the automatic delete bit.
2070 ///
2071 /// This bit is used by TBranchObject::ReadBasket to decide if an object
2072 /// referenced by a TBranchObject must be deleted or not before reading
2073 /// a new entry.
2074 ///
2075 /// If autodel is kTRUE, this existing object will be deleted, a new object
2076 /// created by the default constructor, then read from disk by the streamer.
2077 ///
2078 /// If autodel is kFALSE, the existing object is not deleted. Root assumes
2079 /// that the user is taking care of deleting any internal object or array
2080 /// (this can be done in the streamer).
2081 
2083 {
2084  if (autodel) {
2085  SetBit(kAutoDelete, 1);
2086  } else {
2087  SetBit(kAutoDelete, 0);
2088  }
2089 }
2090 
2091 ////////////////////////////////////////////////////////////////////////////////
2092 /// Set the basket size
2093 /// The function makes sure that the basket size is greater than fEntryOffsetlen
2094 
2096 {
2097  Int_t minsize = 100 + fName.Length();
2098  if (buffsize < minsize+fEntryOffsetLen) buffsize = minsize+fEntryOffsetLen;
2099  fBasketSize = buffsize;
2100  TBasket *basket = (TBasket*)fBaskets[fWriteBasket];
2101  if (basket) {
2102  basket->AdjustSize(fBasketSize);
2103  }
2104 }
2105 
2106 ////////////////////////////////////////////////////////////////////////////////
2107 /// Set address of this branch directly from a TBuffer to avoid streaming.
2108 ///
2109 /// Note: We do not take ownership of the buffer.
2110 
2112 {
2113  // Check this is possible
2114  if ( (fNleaves != 1)
2115  || (strcmp("TLeafObject",fLeaves.UncheckedAt(0)->ClassName())!=0) ) {
2116  Error("TBranch::SetAddress","Filling from a TBuffer can only be done with a not split object branch. Request ignored.");
2117  } else {
2118  fReadEntry = -1;
2119  fNextBasketEntry = -1;
2120  fFirstBasketEntry = -1;
2121  // Note: We do not take ownership of the buffer.
2122  fEntryBuffer = buf;
2123  }
2124 }
2125 
2126 ////////////////////////////////////////////////////////////////////////////////
2127 /// Set compression algorithm.
2128 
2130 {
2131  if (algorithm < 0 || algorithm >= ROOT::kUndefinedCompressionAlgorithm) algorithm = 0;
2132  if (fCompress < 0) {
2133  fCompress = 100 * algorithm + 1;
2134  } else {
2135  int level = fCompress % 100;
2136  fCompress = 100 * algorithm + level;
2137  }
2138 
2140  for (Int_t i=0;i<nb;i++) {
2141  TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
2142  branch->SetCompressionAlgorithm(algorithm);
2143  }
2144 }
2145 
2146 ////////////////////////////////////////////////////////////////////////////////
2147 /// Set compression level.
2148 
2150 {
2151  if (level < 0) level = 0;
2152  if (level > 99) level = 99;
2153  if (fCompress < 0) {
2154  fCompress = level;
2155  } else {
2156  int algorithm = fCompress / 100;
2157  if (algorithm >= ROOT::kUndefinedCompressionAlgorithm) algorithm = 0;
2158  fCompress = 100 * algorithm + level;
2159  }
2160 
2162  for (Int_t i=0;i<nb;i++) {
2163  TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
2164  branch->SetCompressionLevel(level);
2165  }
2166 }
2167 
2168 ////////////////////////////////////////////////////////////////////////////////
2169 /// Set compression settings.
2170 
2172 {
2173  fCompress = settings;
2174 
2176  for (Int_t i=0;i<nb;i++) {
2177  TBranch *branch = (TBranch*)fBranches.UncheckedAt(i);
2178  branch->SetCompressionSettings(settings);
2179  }
2180 }
2181 
2182 ////////////////////////////////////////////////////////////////////////////////
2183 /// Update the default value for the branch's fEntryOffsetLen if and only if
2184 /// it was already non zero (and the new value is not zero)
2185 /// If updateExisting is true, also update all the existing branches.
2186 
2187 void TBranch::SetEntryOffsetLen(Int_t newdefault, Bool_t updateExisting)
2188 {
2189  if (fEntryOffsetLen && newdefault) {
2190  fEntryOffsetLen = newdefault;
2191  }
2192  if (updateExisting) {
2194  TBranch *b;
2195  while ( ( b = (TBranch*)next() ) ) {
2196  b->SetEntryOffsetLen( newdefault, kTRUE );
2197  }
2198  }
2199 }
2200 
2201 ////////////////////////////////////////////////////////////////////////////////
2202 /// Set the number of entries in this branch.
2203 
2205 {
2206  fEntries = entries;
2207  fEntryNumber = entries;
2208 }
2209 
2210 ////////////////////////////////////////////////////////////////////////////////
2211 /// Set file where this branch writes/reads its buffers.
2212 /// By default the branch buffers reside in the file where the
2213 /// Tree was created.
2214 /// If the file name where the tree was created is an absolute
2215 /// path name or an URL (e.g. /castor/... or root://host/...)
2216 /// and if the fname is not an absolute path name or an URL then
2217 /// the path of the tree file is prepended to fname to make the
2218 /// branch file relative to the tree file. In this case one can
2219 /// move the tree + all branch files to a different location in
2220 /// the file system and still access the branch files.
2221 /// The ROOT file will be connected only when necessary.
2222 /// If called by TBranch::Fill (via TBasket::WriteFile), the file
2223 /// will be created with the option "recreate".
2224 /// If called by TBranch::GetEntry (via TBranch::GetBasket), the file
2225 /// will be opened in read mode.
2226 /// To open a file in "update" mode or with a certain compression
2227 /// level, use TBranch::SetFile(TFile *file).
2228 
2230 {
2231  if (file == 0) file = fTree->GetCurrentFile();
2232  fDirectory = (TDirectory*)file;
2233  if (file == fTree->GetCurrentFile()) fFileName = "";
2234  else fFileName = file->GetName();
2235 
2236  if (file && fCompress == -1) {
2237  fCompress = file->GetCompressionLevel();
2238  }
2239 
2240  // Apply to all existing baskets.
2241  TIter nextb(GetListOfBaskets());
2242  TBasket *basket;
2243  while ((basket = (TBasket*)nextb())) {
2244  basket->SetParent(file);
2245  }
2246 
2247  // Apply to sub-branches as well.
2249  TBranch *branch;
2250  while ((branch = (TBranch*)next())) {
2251  branch->SetFile(file);
2252  }
2253 }
2254 
2255 ////////////////////////////////////////////////////////////////////////////////
2256 /// Set file where this branch writes/reads its buffers.
2257 /// By default the branch buffers reside in the file where the
2258 /// Tree was created.
2259 /// If the file name where the tree was created is an absolute
2260 /// path name or an URL (e.g. /castor/... or root://host/...)
2261 /// and if the fname is not an absolute path name or an URL then
2262 /// the path of the tree file is prepended to fname to make the
2263 /// branch file relative to the tree file. In this case one can
2264 /// move the tree + all branch files to a different location in
2265 /// the file system and still access the branch files.
2266 /// The ROOT file will be connected only when necessary.
2267 /// If called by TBranch::Fill (via TBasket::WriteFile), the file
2268 /// will be created with the option "recreate".
2269 /// If called by TBranch::GetEntry (via TBranch::GetBasket), the file
2270 /// will be opened in read mode.
2271 /// To open a file in "update" mode or with a certain compression
2272 /// level, use TBranch::SetFile(TFile *file).
2273 
2274 void TBranch::SetFile(const char* fname)
2275 {
2276  fFileName = fname;
2277  fDirectory = 0;
2278 
2279  //apply to sub-branches as well
2281  TBranch *branch;
2282  while ((branch = (TBranch*)next())) {
2283  branch->SetFile(fname);
2284  }
2285 }
2286 
2287 ////////////////////////////////////////////////////////////////////////////////
2288 /// Set the branch in a mode where the object are decomposed
2289 /// (Also known as MakeClass mode).
2290 /// Return whether the setting was possible (it is not possible for
2291 /// TBranch and TBranchObject).
2292 
2294 {
2295  // Regular TBranch and TBrancObject can not be in makeClass mode
2296  return kFALSE;
2297 }
2298 
2299 ////////////////////////////////////////////////////////////////////////////////
2300 /// Set object this branch is pointing to.
2301 
2302 void TBranch::SetObject(void * /* obj */)
2303 {
2304  if (TestBit(kDoNotProcess)) {
2305  return;
2306  }
2307  Warning("SetObject","is not supported in TBranch objects");
2308 }
2309 
2310 ////////////////////////////////////////////////////////////////////////////////
2311 /// Set branch status to Process or DoNotProcess.
2312 
2314 {
2315  if (status) ResetBit(kDoNotProcess);
2316  else SetBit(kDoNotProcess);
2317 }
2318 
2319 ////////////////////////////////////////////////////////////////////////////////
2320 /// Stream a class object
2321 
2322 void TBranch::Streamer(TBuffer& b)
2323 {
2324  if (b.IsReading()) {
2325  UInt_t R__s, R__c;
2326  fTree = 0; // Will be set by TTree::Streamer
2327  fAddress = 0;
2328  gROOT->SetReadingObject(kTRUE);
2329 
2330  // Reset transients.
2332  fCurrentBasket = 0;
2333  fFirstBasketEntry = -1;
2334  fNextBasketEntry = -1;
2335 
2336  Version_t v = b.ReadVersion(&R__s, &R__c);
2337  if (v > 9) {
2338  b.ReadClassBuffer(TBranch::Class(), this, v, R__s, R__c);
2339 
2340  if (fWriteBasket>=fBaskets.GetSize()) {
2341  fBaskets.Expand(fWriteBasket+1);
2342  }
2343  fDirectory = 0;
2344  fNleaves = fLeaves.GetEntriesFast();
2345  for (Int_t i=0;i<fNleaves;i++) {
2346  TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
2347  leaf->SetBranch(this);
2348  }
2349 
2350  fNBaskets = fBaskets.GetEntries();
2351  for (Int_t j=fWriteBasket,n=0;j>=0 && n<fNBaskets;--j) {
2352  TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
2353  if (bk) {
2354  bk->SetBranch(this);
2355  // GetTree()->IncrementTotalBuffers(bk->GetBufferSize());
2356  ++n;
2357  }
2358  }
2359  if (fWriteBasket >= fMaxBaskets) {
2360  //old versions may need this fix
2362  fBasketBytes[fWriteBasket] = fBasketBytes[fWriteBasket-1];
2364  fBasketSeek [fWriteBasket] = fBasketSeek [fWriteBasket-1];
2365 
2366  }
2367  if (!fSplitLevel && fBranches.GetEntriesFast()) fSplitLevel = 1;
2368  gROOT->SetReadingObject(kFALSE);
2369  if (IsA() == TBranch::Class()) {
2370  if (fNleaves == 0) {
2372  } else if (fNleaves == 1) {
2374  } else if (fNleaves == 2) {
2376  } else {
2378  }
2379  }
2380  return;
2381  }
2382  //====process old versions before automatic schema evolution
2383  Int_t n,i,j,ijunk;
2384  if (v > 5) {
2385  Stat_t djunk;
2386  TNamed::Streamer(b);
2387  if (v > 7) TAttFill::Streamer(b);
2388  b >> fCompress;
2389  b >> fBasketSize;
2390  b >> fEntryOffsetLen;
2391  b >> fWriteBasket;
2392  b >> ijunk; fEntryNumber = (Long64_t)ijunk;
2393  b >> fOffset;
2394  b >> fMaxBaskets;
2395  if (v > 6) b >> fSplitLevel;
2396  b >> djunk; fEntries = (Long64_t)djunk;
2397  b >> djunk; fTotBytes = (Long64_t)djunk;
2398  b >> djunk; fZipBytes = (Long64_t)djunk;
2399 
2400  fBranches.Streamer(b);
2401  fLeaves.Streamer(b);
2402  fBaskets.Streamer(b);
2406  Char_t isArray;
2407  b >> isArray;
2408  b.ReadFastArray(fBasketBytes,fMaxBaskets);
2409  b >> isArray;
2410  for (i=0;i<fMaxBaskets;i++) {b >> ijunk; fBasketEntry[i] = ijunk;}
2411  b >> isArray;
2412  for (i=0;i<fMaxBaskets;i++) {
2413  if (isArray == 2) b >> fBasketSeek[i];
2414  else {Int_t bsize; b >> bsize; fBasketSeek[i] = (Long64_t)bsize;};
2415  }
2416  fFileName.Streamer(b);
2417  b.CheckByteCount(R__s, R__c, TBranch::IsA());
2418  fDirectory = 0;
2419  fNleaves = fLeaves.GetEntriesFast();
2420  for (i=0;i<fNleaves;i++) {
2421  TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
2422  leaf->SetBranch(this);
2423  }
2424  fNBaskets = fBaskets.GetEntries();
2425  for (j=fWriteBasket,n=0;j>=0 && n<fNBaskets;--j) {
2426  TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
2427  if (bk) {
2428  bk->SetBranch(this);
2429  //GetTree()->IncrementTotalBuffers(bk->GetBufferSize());
2430  ++n;
2431  }
2432  }
2433  if (fWriteBasket >= fMaxBaskets) {
2434  //old versions may need this fix
2436  fBasketBytes[fWriteBasket] = fBasketBytes[fWriteBasket-1];
2438  fBasketSeek [fWriteBasket] = fBasketSeek [fWriteBasket-1];
2439 
2440  }
2441  // Check Byte Count is not needed since it was done in ReadBuffer
2442  if (!fSplitLevel && fBranches.GetEntriesFast()) fSplitLevel = 1;
2443  gROOT->SetReadingObject(kFALSE);
2444  b.CheckByteCount(R__s, R__c, TBranch::IsA());
2445  if (IsA() == TBranch::Class()) {
2446  if (fNleaves == 0) {
2448  } else if (fNleaves == 1) {
2450  } else if (fNleaves == 2) {
2452  } else {
2454  }
2455  }
2456  return;
2457  }
2458  //====process very old versions
2459  Stat_t djunk;
2460  TNamed::Streamer(b);
2461  b >> fCompress;
2462  b >> fBasketSize;
2463  b >> fEntryOffsetLen;
2464  b >> fMaxBaskets;
2465  b >> fWriteBasket;
2466  b >> ijunk; fEntryNumber = (Long64_t)ijunk;
2467  b >> djunk; fEntries = (Long64_t)djunk;
2468  b >> djunk; fTotBytes = (Long64_t)djunk;
2469  b >> djunk; fZipBytes = (Long64_t)djunk;
2470  b >> fOffset;
2471  fBranches.Streamer(b);
2472  fLeaves.Streamer(b);
2473  fNleaves = fLeaves.GetEntriesFast();
2474  for (i=0;i<fNleaves;i++) {
2475  TLeaf *leaf = (TLeaf*)fLeaves.UncheckedAt(i);
2476  leaf->SetBranch(this);
2477  }
2478  fBaskets.Streamer(b);
2479  Int_t nbaskets = fBaskets.GetEntries();
2480  for (j=fWriteBasket,n=0;j>0 && n<nbaskets;--j) {
2481  TBasket *bk = (TBasket*)fBaskets.UncheckedAt(j);
2482  if (bk) {
2483  bk->SetBranch(this);
2484  //GetTree()->IncrementTotalBuffers(bk->GetBufferSize());
2485  ++n;
2486  }
2487  }
2489  b >> n;
2490  for (i=0;i<n;i++) {b >> ijunk; fBasketEntry[i] = ijunk;}
2492  if (v > 4) {
2493  n = b.ReadArray(fBasketBytes);
2494  } else {
2495  for (n=0;n<fMaxBaskets;n++) fBasketBytes[n] = 0;
2496  }
2497  if (v < 2) {
2499  for (n=0;n<fWriteBasket;n++) {
2500  TBasket *basket = GetBasket(n);
2501  fBasketSeek[n] = basket ? basket->GetSeekKey() : 0;
2502  }
2503  } else {
2505  b >> n;
2506  for (n=0;n<fMaxBaskets;n++) {
2507  Int_t aseek;
2508  b >> aseek;
2509  fBasketSeek[n] = Long64_t(aseek);
2510  }
2511  }
2512  if (v > 2) {
2513  fFileName.Streamer(b);
2514  }
2515  fDirectory = 0;
2516  if (v < 4) SetAutoDelete(kTRUE);
2517  if (!fSplitLevel && fBranches.GetEntriesFast()) fSplitLevel = 1;
2518  gROOT->SetReadingObject(kFALSE);
2519  b.CheckByteCount(R__s, R__c, TBranch::IsA());
2520  //====end of old versions
2521  if (IsA() == TBranch::Class()) {
2522  if (fNleaves == 0) {
2524  } else if (fNleaves == 1) {
2526  } else if (fNleaves == 2) {
2528  } else {
2530  }
2531  }
2532  } else {
2533  Int_t maxBaskets = fMaxBaskets;
2534  fMaxBaskets = fWriteBasket+1;
2535  if (fMaxBaskets < 10) fMaxBaskets=10;
2536  TBasket *writebasket = 0;
2537  if (fNBaskets == 1) {
2538  writebasket = (TBasket*)fBaskets.UncheckedAt(fWriteBasket);
2539  if (writebasket && writebasket->GetNevBuf()==0) {
2540  fBaskets[fWriteBasket] = 0;
2541  } else {
2542  writebasket = 0;
2543  }
2544  }
2545  b.WriteClassBuffer(TBranch::Class(),this);
2546  if (writebasket) {
2547  fBaskets[fWriteBasket] = writebasket;
2548  }
2549  fMaxBaskets = maxBaskets;
2550  }
2551 }
2552 
2553 ////////////////////////////////////////////////////////////////////////////////
2554 /// Write the current basket to disk and return the number of bytes
2555 /// written to the file.
2556 
2558 {
2559  Int_t nevbuf = basket->GetNevBuf();
2560  if (fEntryOffsetLen > 10 && (4*nevbuf) < fEntryOffsetLen ) {
2561  // Make sure that the fEntryOffset array does not stay large unnecessarily.
2562  fEntryOffsetLen = nevbuf < 3 ? 10 : 4*nevbuf; // assume some fluctuations.
2563  } else if (fEntryOffsetLen && nevbuf > fEntryOffsetLen) {
2564  // Increase the array ...
2565  fEntryOffsetLen = 2*nevbuf; // assume some fluctuations.
2566  }
2567 
2568  Int_t nout = basket->WriteBuffer(); // Write buffer
2569  fBasketBytes[where] = basket->GetNbytes();
2570  fBasketSeek[where] = basket->GetSeekKey();
2571  Int_t addbytes = basket->GetObjlen() + basket->GetKeylen();
2572  TBasket *reusebasket = 0;
2573  if (nout>0) {
2574  // The Basket was written so we can now safely reuse it.
2575  fBaskets[where] = 0;
2576 
2577  reusebasket = basket;
2578  reusebasket->Reset();
2579 
2580  fZipBytes += nout;
2581  fTotBytes += addbytes;
2582  fTree->AddTotBytes(addbytes);
2583  fTree->AddZipBytes(nout);
2584  }
2585 
2586  if (where==fWriteBasket) {
2587  ++fWriteBasket;
2588  if (fWriteBasket >= fMaxBaskets) {
2590  }
2591  if (reusebasket && reusebasket == fCurrentBasket) {
2592  // The 'current' basket has Reset, so if we need it we will need
2593  // to reload it.
2594  fCurrentBasket = 0;
2595  fFirstBasketEntry = -1;
2596  fNextBasketEntry = -1;
2597  }
2598  fBaskets.AddAtAndExpand(reusebasket,fWriteBasket);
2600  } else {
2601  --fNBaskets;
2602  fBaskets[where] = 0;
2603  basket->DropBuffers();
2604  if (basket == fCurrentBasket) {
2605  fCurrentBasket = 0;
2606  fFirstBasketEntry = -1;
2607  fNextBasketEntry = -1;
2608  }
2609  delete basket;
2610  }
2611 
2612  return nout;
2613 }
2614 
2615 ////////////////////////////////////////////////////////////////////////////////
2616 ///set the first entry number (case of TBranchSTL)
2617 
2619 {
2620  fFirstEntry = entry;
2621  fEntries = 0;
2622  fEntryNumber = entry;
2623  if( fBasketEntry )
2624  fBasketEntry[0] = entry;
2625  for( Int_t i = 0; i < fBranches.GetEntriesFast(); ++i )
2626  ((TBranch*)fBranches[i])->SetFirstEntry( entry );
2627 }
2628 
2629 ////////////////////////////////////////////////////////////////////////////////
2630 /// If the branch address is not set, we set all addresses starting with
2631 /// the top level parent branch.
2632 
2634 {
2635  // Nothing to do for regular branch, the TLeaf already did it.
2636 }
2637 
2638 ////////////////////////////////////////////////////////////////////////////////
2639 /// Refresh the value of fDirectory (i.e. where this branch writes/reads its buffers)
2640 /// with the current value of fTree->GetCurrentFile unless this branch has been
2641 /// redirected to a different file. Also update the sub-branches.
2642 
2644 {
2645  TFile *file = fTree->GetCurrentFile();
2646  if (fFileName.Length() == 0) {
2647  fDirectory = file;
2648 
2649  // Apply to all existing baskets.
2650  TIter nextb(GetListOfBaskets());
2651  TBasket *basket;
2652  while ((basket = (TBasket*)nextb())) {
2653  basket->SetParent(file);
2654  }
2655  }
2656 
2657  // Apply to sub-branches as well.
2659  TBranch *branch;
2660  while ((branch = (TBranch*)next())) {
2661  branch->UpdateFile();
2662  }
2663 }
virtual Bool_t GetMakeClass() const
Return whether this branch is in a mode where the object are decomposed or not (Also known as MakeCla...
Definition: TBranch.cxx:1522
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
Definition: TLeaf.cxx:276
void Init(const char *name, const char *leaflist, Int_t compress)
Definition: TBranch.cxx:274
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
Int_t ReadBasketBytes(Long64_t pos, TFile *file)
Read basket buffers in memory and cleanup.
Definition: TBasket.cxx:645
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
Int_t fNBaskets
Definition: TBranch.h:76
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:88
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
virtual void AddTotBytes(Int_t tot)
Definition: TTree.h:296
A TLeaf for an 8 bit Integer data type.
Definition: TLeafB.h:28
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:945
virtual void SetBufferAddress(TBuffer *entryBuffer)
Set address of this branch directly from a TBuffer to avoid streaming.
Definition: TBranch.cxx:2111
An array of TObjects.
Definition: TObjArray.h:39
virtual void SetReadMode()
Set read mode of basket.
Definition: TBasket.cxx:745
A TLeaf for a 64 bit floating point data type.
Definition: TLeafD.h:28
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void Update(Int_t newlast)
Definition: TBasket.h:95
Int_t * GetEntryOffset() const
Definition: TBasket.h:77
virtual void UpdateFile()
Refresh the value of fDirectory (i.e.
Definition: TBranch.cxx:2643
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket...
Definition: TBufferFile.h:51
virtual void SetAddress(void *add)
Set address of this branch.
Definition: TBranch.cxx:2048
Int_t ReadBasketBuffers(Long64_t pos, Int_t len, TFile *file)
Read basket buffers in memory and cleanup.
Definition: TBasket.cxx:435
Int_t fOffset
Definition: TBranch.h:74
long long Long64_t
Definition: RtypesCore.h:69
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1459
Bool_t IsReading() const
Definition: TBuffer.h:81
Option_t * GetDrawOption() const
Get option used by the graphics system to draw this object.
Definition: TBrowser.h:108
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
virtual void IncrementTotalBuffers(Int_t nbytes)
Definition: TTree.h:460
short Version_t
Definition: RtypesCore.h:61
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Ssiz_t Length() const
Definition: TString.h:390
TObjArray * GetListOfBaskets()
Definition: TBranch.h:176
virtual ~TBranch()
Destructor.
Definition: TBranch.cxx:410
virtual void AddZipBytes(Int_t zip)
Definition: TTree.h:297
Long64_t fEntries
Pointer to the current basket.
Definition: TBranch.h:84
float Float_t
Definition: RtypesCore.h:53
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:1040
virtual Int_t GetExpectedType(TClass *&clptr, EDataType &type)
Fill expectedClass and expectedType with information on the data type of the object/values contained ...
Definition: TBranch.cxx:1362
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:527
A cache when reading files over the network.
const char Option_t
Definition: RtypesCore.h:62
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:328
Long64_t fZipBytes
Definition: TBranch.h:87
This class represents a WWW compatible URL.
Definition: TUrl.h:41
const UInt_t kByteCountMask
Definition: TBufferFile.cxx:55
ReadLeaves_t fReadLeaves
Definition: TBranch.h:106
Int_t FillEntryBuffer(TBasket *basket, TBuffer *buf, Int_t &lnew)
Copy the data from fEntryBuffer into the current basket.
Definition: TBranch.cxx:794
void SetCompressionAlgorithm(Int_t algorithm=0)
Set compression algorithm.
Definition: TBranch.cxx:2129
virtual void DropBaskets(Option_t *option="")
Loop on all branch baskets.
Definition: TBranch.cxx:626
virtual void SetStatus(Bool_t status=1)
Set branch status to Process or DoNotProcess.
Definition: TBranch.cxx:2313
void ReadLeaves2Impl(TBuffer &b)
Read two leaves without the overhead of a loop.
Definition: TBranch.cxx:1853
virtual void SetFirstEntry(Long64_t entry)
set the first entry number (case of TBranchSTL)
Definition: TBranch.cxx:2618
virtual Int_t AddBranch(TBranch *, Bool_t=kFALSE)
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
void SetCompressionLevel(Int_t level=1)
Set compression level.
Definition: TBranch.cxx:2149
Long64_t GetTotBytes(Option_t *option="") const
Return total number of bytes in the branch (excluding current buffer) if option ="*" includes all sub...
Definition: TBranch.cxx:1617
virtual TLeaf * FindLeaf(const char *name)
Find the leaf corresponding to the name 'searchname'.
Definition: TBranch.cxx:939
virtual void Print(Option_t *option="") const
Print TBranch parameters.
Definition: TBranch.cxx:1726
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
TBasket * fCurrentBasket
Next entry that will requires us to go to the next basket.
Definition: TBranch.h:83
virtual TBasket * CreateBasket(TBranch *)
Create a basket for this tree and given branch.
Definition: TTree.cxx:3504
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:340
TObjArray fBaskets
Definition: TBranch.h:90
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
virtual Bool_t IsLearning() const
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1088
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:996
bool Bool_t
Definition: RtypesCore.h:59
A TLeaf for a bool data type.
Definition: TLeafO.h:28
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
TBranch * GetBranch() const
Definition: TLeaf.h:70
virtual Long64_t GetBasketSeek(Int_t basket) const
Return address of basket in the file.
Definition: TBranch.cxx:1143
const int minsize
Int_t fNleaves
Definition: TBranch.h:78
const UInt_t kNewClassTag
Definition: TBufferFile.cxx:53
Type GetType(const std::string &Name)
Definition: Systematics.cxx:34
TObjArray fLeaves
Definition: TBranch.h:89
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
TString & Prepend(const char *cs)
Definition: TString.h:604
Long64_t * fBasketSeek
Definition: TBranch.h:93
virtual void DeleteBaskets(Option_t *option="")
Loop on all branch baskets.
Definition: TBranch.cxx:595
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition: TTree.cxx:5006
A TLeaf for a variable length string.
Definition: TLeafC.h:28
size_t
Definition: TBuffer.cxx:28
virtual Int_t GetRow(Int_t row)
Return all elements of one row unpacked in internal array fValues [Actually just returns 1 (...
Definition: TBranch.cxx:1513
virtual Long64_t GetSeekKey() const
Definition: TKey.h:91
TBasket * GetFreshBasket()
Return a fresh basket by either resusing an existing basket that needs to be drop (according to TTree...
Definition: TBranch.cxx:1416
TString GetRealFileName() const
Get real file name.
Definition: TBranch.cxx:1472
virtual void SetupAddresses()
If the branch address is not set, we set all addresses starting with the top level parent branch...
Definition: TBranch.cxx:2633
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
Long64_t fFirstBasketEntry
Current entry number when reading.
Definition: TBranch.h:81
void SetBranch(TBranch *branch)
Definition: TBasket.h:91
Int_t * fBasketBytes
Definition: TBranch.h:91
virtual TList * GetBrowsables()
Returns (and, if 0, creates) browsable objects for this branch See TVirtualBranchBrowsable::FillListO...
Definition: TBranch.cxx:1153
Long64_t fEntryNumber
Definition: TBranch.h:73
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=1, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3851
const char * Data() const
Definition: TString.h:349
TFileCacheRead * GetCacheRead(TObject *tree=0) const
Return a pointer to the current read cache.
Definition: TFile.cxx:1196
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:946
static Int_t FillListOfBrowsables(TList &list, const TBranch *branch, const TVirtualBranchBrowsable *parent=0)
Askes all registered generators to fill their browsables into the list.
Int_t fWriteBasket
Definition: TBranch.h:72
virtual TObjArray * GetListOfBranches()
Definition: TTree.h:405
Long64_t fTotBytes
Definition: TBranch.h:86
Fill Area Attributes class.
Definition: TAttFill.h:32
Int_t GetCompressionLevel() const
Definition: TFile.h:357
void Class()
Definition: Class.C:29
void SetLast(Int_t last)
Set index of last object in array, effectively truncating the array.
Definition: TObjArray.cxx:704
Int_t bsize[]
Definition: SparseFit4.cxx:31
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
virtual void Browse(TBrowser *b)
Browser interface.
Definition: TBranch.cxx:569
Int_t GetNbytes() const
Definition: TKey.h:88
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
void ReadLeavesImpl(TBuffer &b)
Pointer to the FillLeaves implementation to use.
Definition: TBranch.cxx:1827
virtual Bool_t SetMakeClass(Bool_t decomposeObj=kTRUE)
Set the branch in a mode where the object are decomposed (Also known as MakeClass mode)...
Definition: TBranch.cxx:2293
#define R__likely(expr)
Definition: TBranch.cxx:58
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1139
virtual TBranch * FindBranch(const char *name)
Find the immediate sub-branch with passed name.
Definition: TBranch.cxx:893
virtual void Reset()
Reset the basket to the starting state.
Definition: TBasket.cxx:660
virtual Int_t WriteBuffer()
Write buffer of this basket on the current file.
Definition: TBasket.cxx:919
const Int_t kDoNotProcess
Definition: TBranch.h:52
const int maxsize
Long64_t GetZipBytes(Option_t *option="") const
Return total number of zip bytes in the branch if option ="*" includes all sub-branches of this branc...
Definition: TBranch.cxx:1635
TObjArray * GetListOfBranches()
Definition: TBranch.h:177
virtual void SetBranch(TBranch *branch)
Definition: TLeaf.h:100
TBasket * GetBasket(Int_t basket)
Return pointer to basket basketnumber in this Branch.
Definition: TBranch.cxx:1081
char * Buffer() const
Definition: TBuffer.h:91
Int_t fMaxBaskets
Definition: TBranch.h:75
Int_t GetNevBuf() const
Definition: TBasket.h:79
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual void SetAddress(void *add=0)
Definition: TLeaf.h:124
virtual void FillBasket(TBuffer &b)
Pack leaf elements in Basket output buffer.
Definition: TLeaf.cxx:146
Int_t fSplitLevel
Number of baskets in memory.
Definition: TBranch.h:77
A doubly linked list.
Definition: TList.h:47
virtual void ResetAfterMerge(TFileMergeInfo *)
Reset a Branch.
Definition: TBranch.cxx:1964
virtual TFile * GetFile() const
Definition: TDirectory.h:152
virtual Int_t Fill()
Loop on all leaves of this branch to fill Basket buffer.
Definition: TBranch.cxx:723
TBuffer * GetBufferRef() const
Definition: TKey.h:81
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
Int_t GetBufferSize() const
Definition: TBasket.h:75
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:41
virtual void AddLastBasket(Long64_t startEntry)
Add the start entry of the write basket (not yet created)
Definition: TBranch.cxx:549
Int_t WriteBasket(TBasket *basket, Int_t where)
Write the current basket to disk and return the number of bytes written to the file.
Definition: TBranch.cxx:2557
TBuffer * fEntryBuffer
Definition: TBranch.h:100
virtual char * ReadString(char *s, Int_t max)=0
static Int_t fgCount
Definition: TBranch.h:68
void FillLeavesImpl(TBuffer &b)
Loop on all leaves of this branch to fill Basket buffer.
Definition: TBranch.cxx:1862
virtual const char * GetTypeName() const
Definition: TLeaf.h:81
virtual Int_t GetEntryExport(Long64_t entry, Int_t getall, TClonesArray *list, Int_t n)
Read all leaves of an entry and export buffers to real objects in a TClonesArray list.
Definition: TBranch.cxx:1290
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:221
Int_t fBasketSize
Definition: TBranch.h:70
void SetCompressionSettings(Int_t settings=1)
Set compression settings.
Definition: TBranch.cxx:2171
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
virtual void SetEntries(Long64_t entries)
Set the number of entries in this branch.
Definition: TBranch.cxx:2204
TList * fBrowsables
Buffer used to directly pass the content without streaming.
Definition: TBranch.h:101
Int_t GetLast() const
Definition: TBasket.h:81
virtual void AdjustSize(Int_t newsize)
Increase the size of the current fBuffer up to newsize.
Definition: TBasket.cxx:148
virtual TObject * RemoveAt(Int_t idx)
Remove object at index idx.
Definition: TObjArray.cxx:629
TDirectory * GetDirectory() const
Definition: TTree.h:381
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
Long64_t GetTotalSize(Option_t *option="") const
Return total number of bytes in the branch (including current buffer)
Definition: TBranch.cxx:1591
TClass * IsA() const
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1532
const Int_t kIsClone
Definition: TBranch.h:53
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
FillLeaves_t fFillLeaves
Definition: TBranch.h:108
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
virtual void MakeFree(Long64_t first, Long64_t last)
Mark unused bytes on the file.
Definition: TFile.cxx:1388
Long64_t fNextBasketEntry
First entry in the current basket.
Definition: TBranch.h:82
Manages buffers for branches of a Tree.
Definition: TBasket.h:38
void SetReadMode()
Set buffer in read mode.
Definition: TBuffer.cxx:269
TLine * l
Definition: textangle.C:4
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all leaves of entry and return total number of bytes read.
Definition: TBranch.cxx:1198
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
A TLeaf for a 32 bit floating point data type.
Definition: TLeafF.h:28
const char * GetAnchor() const
Definition: TUrl.h:79
TBranch * GetSubBranch(const TBranch *br) const
Find the parent branch of child.
Definition: TBranch.cxx:1553
Long64_t entry
TString fName
Definition: TNamed.h:36
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:238
TTree * GetTree() const
Definition: TBranch.h:183
virtual void KeepCircular(Long64_t maxEntries)
keep a maximum of fMaxEntries in memory
Definition: TBranch.cxx:1672
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:71
Int_t * GetDisplacement() const
Definition: TBasket.h:76
#define Printf
Definition: TGeoToOCC.h:18
Int_t GetCompressionSettings() const
Definition: TFile.h:363
virtual void SetParent(const TObject *parent)
Set parent in key buffer.
Definition: TKey.cxx:1287
virtual void SetOffset(Int_t offset=0)
Definition: TLeaf.h:103
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition: TUrl.cxx:385
virtual void SetBasketSize(Int_t buffsize)
Set the basket size The function makes sure that the basket size is greater than fEntryOffsetlen.
Definition: TBranch.cxx:2095
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
int Ssiz_t
Definition: RtypesCore.h:63
void SetAnchor(const char *anchor)
Definition: TUrl.h:95
virtual Int_t GetSize() const
Definition: TCollection.h:95
Bool_t fSkipZip
List of TVirtualBranchBrowsables used for Browse()
Definition: TBranch.h:103
Int_t fReadBasket
Number of leaves.
Definition: TBranch.h:79
virtual void ResetAddress()
Reset the address of the branch.
Definition: TBranch.cxx:2017
virtual Int_t GetLenType() const
Definition: TLeaf.h:75
Describe directory structure in memory.
Definition: TDirectory.h:41
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Int_t GetObjlen() const
Definition: TKey.h:89
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:356
int nentries
Definition: THbookFile.cxx:89
Bool_t IsAutoDelete() const
Return kTRUE if an existing object in a TBranchObject must be deleted.
Definition: TBranch.cxx:1652
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
Definition: TObjArray.cxx:369
Int_t GetKeylen() const
Definition: TKey.h:86
EDataType
Definition: TDataType.h:30
TTree * fTree
Definition: TBranch.h:94
void Browse(TBrowser *b)
Browse this collection (called by TBrowser).
TObjArray * GetListOfLeaves()
Definition: TBranch.h:178
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:493
TDirectory * fDirectory
Address of 1st leaf (variable or object)
Definition: TBranch.h:98
virtual void ReadBasket(TBuffer &)
Definition: TLeaf.h:93
virtual void SetUnsigned()
Definition: TLeaf.h:105
double Stat_t
Definition: RtypesCore.h:73
virtual Int_t GetOffset() const
Definition: TLeaf.h:79
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual void ReadBasketExport(TBuffer &, TClonesArray *, Int_t)
Definition: TLeaf.h:94
static void * ReAlloc(void *vp, size_t size)
Reallocate (i.e.
Definition: TStorage.cxx:177
char Char_t
Definition: RtypesCore.h:29
virtual void SetEntryOffsetLen(Int_t len, Bool_t updateSubBranches=kFALSE)
Update the default value for the branch's fEntryOffsetLen if and only if it was already non zero (and...
Definition: TBranch.cxx:2187
virtual void SetFile(TFile *file=0)
Set file where this branch writes/reads its buffers.
Definition: TBranch.cxx:2229
Int_t BufferSize() const
Definition: TBuffer.h:92
A TLeaf for a 16 bit Integer data type.
Definition: TLeafS.h:28
virtual void Refresh(TBranch *b)
Refresh this branch using new information in b This function is called by TTree::Refresh.
Definition: TBranch.cxx:1874
An array of clone (identical) objects.
Definition: TClonesArray.h:32
void ReadLeaves0Impl(TBuffer &b)
Read zero leaves without the overhead of a loop.
Definition: TBranch.cxx:1838
Long64_t * fBasketEntry
Definition: TBranch.h:92
virtual Int_t DropBuffers()
Drop buffers of this basket if it is not the current basket.
Definition: TBasket.cxx:191
virtual void SetSkipZip(Bool_t=kTRUE)
const Ssiz_t kNPOS
Definition: Rtypes.h:115
virtual void PrepareBasket(Long64_t)
Definition: TBasket.h:83
Int_t Length() const
Definition: TBuffer.h:94
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
virtual void Reset(Option_t *option="")
Reset a Branch.
Definition: TBranch.cxx:1923
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
virtual Bool_t IsWritable() const
Definition: TDirectory.h:168
void MakeZombie()
Definition: TObject.h:68
Int_t GetNevBufSize() const
Definition: TBasket.h:80
Long64_t fReadEntry
Current basket number when reading.
Definition: TBranch.h:80
virtual void AddBasket(TBasket &b, Bool_t ondisk, Long64_t startEntry)
Add the basket to this branch.
Definition: TBranch.cxx:476
TBranch * fMother
Pointer to Tree header.
Definition: TBranch.h:95
virtual Int_t LoadBaskets()
Baskets associated to this branch are forced to be in memory.
Definition: TBranch.cxx:1697
virtual void WriteBuf(const void *buf, Int_t max)=0
A TLeaf for a 64 bit Integer data type.
Definition: TLeafL.h:29
#define gPad
Definition: TVirtualPad.h:288
virtual Int_t GetMapCount() const =0
const char * GetIconName() const
Return icon name depending on type of branch.
Definition: TBranch.cxx:1173
void Add(TObject *obj)
Definition: TObjArray.h:75
A TTree object has a header with a name and a title.
Definition: TTree.h:94
Int_t fEntryOffsetLen
Definition: TBranch.h:71
virtual void ResetMap()=0
void ResetBit(UInt_t f)
Definition: TObject.h:172
#define R__unlikely(expr)
Definition: TBranch.cxx:57
Bool_t IsFolder() const
Return kTRUE if more than one leaf or browsables, kFALSE otherwise.
Definition: TBranch.cxx:1660
virtual void ReadBasket(TBuffer &b)
Loop on all leaves of this branch to read Basket buffer.
Definition: TBranch.cxx:1819
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1243
Int_t FlushBaskets()
Flush to disk all the baskets of this branch and any of subbranches.
Definition: TBranch.cxx:994
TObjArray fBranches
Definition: TBranch.h:88
void SetNevBufSize(Int_t n)
Definition: TBasket.h:92
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
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:1381
virtual void SetBufferDisplacement()=0
A TTree is a list of TBranches.
Definition: TBranch.h:58
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranch.cxx:1165
Int_t fCompress
branch counter
Definition: TBranch.h:69
const Bool_t kTRUE
Definition: Rtypes.h:91
TString fFileName
Pointer to directory where this branch buffers are stored.
Definition: TBranch.h:99
virtual Int_t GetBufferDisplacement() const =0
TBranch * fParent
Pointer to top-level parent branch in the tree.
Definition: TBranch.h:96
const Int_t n
Definition: legend1.C:16
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Definition: TMath.h:944
Long64_t fFirstEntry
Definition: TBranch.h:85
virtual void SetWriteMode()
Set write mode of basket.
Definition: TBasket.cxx:754
void ExpandBasketArrays()
Increase BasketEntry buffer of a minimum of 10 locations and a maximum of 50 per cent of current size...
Definition: TBranch.cxx:694
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:466
A TLeaf for an Integer data type.
Definition: TLeafI.h:29
virtual void SetObject(void *objadd)
Set object this branch is pointing to.
Definition: TBranch.cxx:2302
ClassImp(TBranch) TBranch
Default constructor. Used for I/O by default.
Definition: TBranch.cxx:75
static Int_t * ReAllocInt(Int_t *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition: TStorage.cxx:289
void SetWriteMode()
Set buffer in write mode.
Definition: TBuffer.cxx:282
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t ReadArray(Bool_t *&b)=0
virtual TObjArray * GetListOfLeaves()
Definition: TTree.h:406
void ReadLeaves1Impl(TBuffer &b)
Read one leaf without the overhead of a loop.
Definition: TBranch.cxx:1845
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898
static void ResetCount()
Static function resetting fgCount.
Definition: TBranch.cxx:2040
virtual void MoveEntries(Int_t dentries)
Remove the first dentries of this basket, moving entries at dentries to the start of the buffer...
Definition: TBasket.cxx:290
virtual void SetAutoDelete(Bool_t autodel=kTRUE)
Set the automatic delete bit.
Definition: TBranch.cxx:2082
char * fAddress
Pointer to parent branch.
Definition: TBranch.h:97
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904