g4tools  5.4.0
branch
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_rroot_branch
5 #define tools_rroot_branch
6 
7 #include "base_leaf"
8 #include "basket"
9 #include "obj_array"
10 #include "seek"
11 #include "ifile"
12 #include "ifac"
13 #include "../mnmx"
14 #include "../forit"
15 #include "../sprintf"
16 #include "dummy" //for TIOFeatures streaming.
17 
18 #include <map>
19 
20 namespace tools {
21 namespace rroot {
22 
23 class branch : public virtual iro {
24  //static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
25 public:
26  static const std::string& s_class() {
27  static const std::string s_v("tools::rroot::branch");
28  return s_v;
29  }
30 public: //iro
31  virtual void* cast(const std::string& a_class) const {
32  if(void* p = cmp_cast<branch>(this,a_class)) return p;
33  return 0;
34  }
35  virtual const std::string& s_cls() const {return s_class();}
36 public:
37  static cid id_class() {return branch_cid();}
38  virtual void* cast(cid a_class) const {
39  if(void* p = cmp_cast<branch>(this,a_class)) {return p;}
40  else return 0;
41  }
42 public:
43  virtual iro* copy() const {return new branch(*this);}
44  virtual bool stream(buffer& a_buffer) {
45  _clear();
46  //::printf("debug : branch::stream : begin\n");
47 
48  int fCompress;
49  int fBasketSize;
50  //int fNleaves;
51  //uint64 m_entries;
52 
53  //uint64 m_tot_bytes;
54  //uint64 m_zip_bytes;
55  int fSplitLevel;
56  uint32 fMaxBaskets;
57  int fOffset;
58 
59  unsigned int s,c;
60  //FIXME gROOT->SetReadingObject(kTRUE);
61  short vers;
62  if(!a_buffer.read_version(vers,s,c)) return false;
63 
64  //::printf("debug : branch::stream : version %d count %d\n",vers,c);
65 
66  if (vers > 5) {
67  //TBranch::Class()->ReadBuffer(b, this, v, s, c);
68  //gBranch = branchSave;
69  //fDirectory = gDirectory;
70  //fNleaves = m_leaves.GetEntriesFast();
71  //if (fFileName.Length() != 0) fDirectory = 0;
72  //gROOT->SetReadingObject(kFALSE);
73  //return;
74  }
75  //====process old versions before automatic schema evolution
76 
77  {uint32 old = a_buffer.length();
78  uint32 id;
79  uint32 m_bits;
80  if(!Object_stream(a_buffer,id,m_bits)) return false;
81  a_buffer.set_offset(old);}
82 
83  if(!Named_stream(a_buffer,m_name,m_title)) return false;
84 
85  //::printf("debug : branch::stream %s %s\n",m_name.c_str(),m_title.c_str());
86 
87  if(vers<=5) {
88  if(!a_buffer.read(fCompress)) return false;
89  if(!a_buffer.read(fBasketSize)) return false;
90  if(!a_buffer.read(fEntryOffsetLen)) return false;
91  if(!a_buffer.read(fMaxBaskets)) return false;
92  if(!a_buffer.read(m_write_basket)) return false;
93  if(!a_buffer.read(m_entry_number)) return false;
94  {double v;
95  if(!a_buffer.read(v)) return false;
96  //m_entries = uint64(v);
97  }
98  {double v;
99  if(!a_buffer.read(v)) return false;
100  //m_tot_bytes = uint64(v);
101  }
102  {double v;
103  if(!a_buffer.read(v)) return false;
104  //m_zip_bytes = uint64(v);
105  }
106  if(!a_buffer.read(fOffset)) return false;
107 
108  } else if(vers<=6) {
109  if(!a_buffer.read(fCompress)) return false;
110  if(!a_buffer.read(fBasketSize)) return false;
111  if(!a_buffer.read(fEntryOffsetLen)) return false;
112  if(!a_buffer.read(m_write_basket)) return false;
113  if(!a_buffer.read(m_entry_number)) return false;
114  if(!a_buffer.read(fOffset)) return false;
115  if(!a_buffer.read(fMaxBaskets)) return false;
116  {double v;
117  if(!a_buffer.read(v)) return false;
118  //m_entries = uint64(v);
119  }
120  {double v;
121  if(!a_buffer.read(v)) return false;
122  //m_tot_bytes = uint64(v);
123  }
124  {double v;
125  if(!a_buffer.read(v)) return false;
126  //m_zip_bytes = uint64(v);
127  }
128 
129  } else if(vers<=7) {
130  if(!a_buffer.read(fCompress)) return false;
131  if(!a_buffer.read(fBasketSize)) return false;
132  if(!a_buffer.read(fEntryOffsetLen)) return false;
133  if(!a_buffer.read(m_write_basket)) return false;
134  if(!a_buffer.read(m_entry_number)) return false;
135  if(!a_buffer.read(fOffset)) return false;
136  if(!a_buffer.read(fMaxBaskets)) return false;
137  if(!a_buffer.read(fSplitLevel)) return false;
138  {double v;
139  if(!a_buffer.read(v)) return false;
140  //m_entries = uint64(v);
141  }
142  {double v;
143  if(!a_buffer.read(v)) return false;
144  //m_tot_bytes = uint64(v);
145  }
146  {double v;
147  if(!a_buffer.read(v)) return false;
148  //m_zip_bytes = uint64(v);
149  }
150 
151  } else if(vers<=9) {
152  {short color,style;
153  if(!AttFill_stream(a_buffer,color,style)) return false;}
154  if(!a_buffer.read(fCompress)) return false;
155  if(!a_buffer.read(fBasketSize)) return false;
156  if(!a_buffer.read(fEntryOffsetLen)) return false;
157  if(!a_buffer.read(m_write_basket)) return false;
158  if(!a_buffer.read(m_entry_number)) return false;
159  if(!a_buffer.read(fOffset)) return false;
160  if(!a_buffer.read(fMaxBaskets)) return false;
161  if(!a_buffer.read(fSplitLevel)) return false;
162  {double v;
163  if(!a_buffer.read(v)) return false;
164  //m_entries = uint64(v);
165  }
166  {double v;
167  if(!a_buffer.read(v)) return false;
168  //m_tot_bytes = uint64(v);
169  }
170  {double v;
171  if(!a_buffer.read(v)) return false;
172  //m_zip_bytes = uint64(v);
173  }
174 
175  } else if(vers<=10) {
176  {short color,style;
177  if(!AttFill_stream(a_buffer,color,style)) return false;}
178 
179  if(!a_buffer.read(fCompress)) return false;
180  if(!a_buffer.read(fBasketSize)) return false;
181  if(!a_buffer.read(fEntryOffsetLen)) return false;
182  if(!a_buffer.read(m_write_basket)) return false;
183  {uint64 v;
184  if(!a_buffer.read(v)) return false;
185  m_entry_number = uint32(v);}
186  if(!a_buffer.read(fOffset)) return false;
187  if(!a_buffer.read(fMaxBaskets)) return false;
188  if(!a_buffer.read(fSplitLevel)) return false;
189 
190  {uint64 v;
191  if(!a_buffer.read(v)) return false;
192  //m_entries = v;
193  }
194  {uint64 v;
195  if(!a_buffer.read(v)) return false;
196  //m_tot_bytes = v;
197  }
198  {uint64 v;
199  if(!a_buffer.read(v)) return false;
200  //m_zip_bytes = v;
201  }
202 
203  } else { //vers>=11
204 
205  {short color,style;
206  if(!AttFill_stream(a_buffer,color,style)) return false;}
207 
208  if(!a_buffer.read(fCompress)) return false;
209  if(!a_buffer.read(fBasketSize)) return false;
210  if(!a_buffer.read(fEntryOffsetLen)) return false;
211  if(!a_buffer.read(m_write_basket)) return false;
212  {uint64 v;
213  if(!a_buffer.read(v)) return false;
214  m_entry_number = uint32(v);}
215  if(vers>=13) {
216  dummy _dummy;
217  if(!_dummy.stream(a_buffer)) { //TIOFeatures fIOFeatures
218  m_out << "tools::rroot::branch::stream : can't read (dummy) TIOFeatures." << std::endl;
219  return false;
220  }
221  }
222  if(!a_buffer.read(fOffset)) return false;
223  if(!a_buffer.read(fMaxBaskets)) return false;
224  if(!a_buffer.read(fSplitLevel)) return false;
225  {uint64 v;
226  if(!a_buffer.read(v)) return false;
227  //m_entries = v;
228  }
229  {uint64 v;
230  if(!a_buffer.read(v)) return false;} //fFirstEntry
231  {uint64 v;
232  if(!a_buffer.read(v)) return false;
233  //m_tot_bytes = v;
234  }
235  {uint64 v;
236  if(!a_buffer.read(v)) return false;
237  //m_zip_bytes = v;
238  }
239  }
240 
241  //::printf("debug : branch::stream : %s : fSplitLevel %d\n",m_name.c_str(),fSplitLevel);
242 
243  //TObjArray
244  //::printf("debug : branch::stream : branches : begin\n");
245  {ifac::args args;
246  if(!m_branches.stream(a_buffer,args)) {
247  m_out << "tools::rroot::branch::stream :"
248  << " can't read branches."
249  << std::endl;
250  return false;
251  }}
252  //::printf("debug : branch::stream : branches : end %d\n",
253  // m_branches.size());
254 
255 /* We see that with LHCb files.
256  if(m_entry_number!=m_entries) {
257  m_out << "tools::rroot::branch::stream :"
258  << " for branch " << sout(m_name) << " :"
259  << " WARNING : m_entry_number!=m_entries."
260  << " m_entry_number " << m_entry_number
261  << " m_entries " << m_entries
262  << std::endl;
263  //return false;
264  }
265 */
266 
267  //TObjArray
268  //::printf("debug : branch::stream : leaves : begin\n");
269  {ifac::args args;
270  //args[ifac::arg_branch()] = this;
271  if(!m_leaves.stream(a_buffer,args)) {
272  m_out << "tools::rroot::branch::stream :"
273  << " can't read leaves."
274  << std::endl;
275  return false;
276  }}
277  //::printf("debug : branch::stream : leaves : end\n");
278 
279  //TObjArray
280  //IMPORTANT : accept_null=true
281  //::printf("debug : branch::stream : streamed_baskets : begin\n");
282  {ifac::args args;
283  if(!m_streamed_baskets.stream(a_buffer,args,true)) {
284  m_out << "tools::rroot::branch::stream :"
285  << " can't read baskets."
286  << std::endl;
287  return false;
288  }}
289  //::printf("debug : branch::stream : streamed_baskets : end\n");
290 
291  //fNleaves = m_leaves.size();
292 
293  if(fMaxBaskets<=0) {
294  m_out << "tools::rroot::branch::stream :"
295  << " fMaxBaskets null."
296  << std::endl;
297  return false;
298  }
299 
300  fBasketEntry = new int[fMaxBaskets];
301  fBasketBytes = new int[fMaxBaskets];
302  fBasketSeek = new seek[fMaxBaskets];
303  {for(uint32 i=0;i<fMaxBaskets;i++) {
304  fBasketEntry[i] = 0;
305  fBasketBytes[i] = 0;
306  fBasketSeek[i] = 0;
307  }}
308 
309  if(vers<6) {
310  {uint32 n;
311  if(!a_buffer.read_array<int>(fMaxBaskets,fBasketEntry,n)) {
312  _clear();
313  return false;
314  }}
315  if(vers<=4) {
316  for (uint32 i=0;i<fMaxBaskets;i++) fBasketBytes[i] = 0;
317  } else {
318  uint32 n;
319  if(!a_buffer.read_array<int>(fMaxBaskets,fBasketBytes,n)) {
320  _clear();
321  return false;
322  }
323  }
324  if(vers<2) {
325  //GB : comment.
326  //for(int i=0;i<m_write_basket;i++) {
327  // fBasketSeek[i] = getBasket(i)->seekKey();
328  //}
329  m_out << "tools::rroot::branch::stream :"
330  << " v < 2. Not (yet) handled."
331  << std::endl;
332  _clear();
333  return false;
334  } else {
335  int n;
336  if(!a_buffer.read(n)) {
337  _clear();
338  return false;
339  }
340  for(int i=0;i<n;i++) {
341  seek32 _s;
342  if(!a_buffer.read(_s)) {
343  _clear();
344  return false;
345  }
346  fBasketSeek[i] = _s;
347  }
348  }
349 
350  } else if(vers<=9) {
351  // See TStreamerInfo::ReadBuffer::ReadBasicPointer
352 
353  //Int_t[fMaxBaskets]
354  {char isArray;
355  if(!a_buffer.read(isArray)) {
356  _clear();
357  return false;
358  }
359  if(isArray) {
360  if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
361  _clear();
362  return false;
363  }
364  }}
365 
366  //Int_t[fMaxBaskets]
367  {char isArray;
368  if(!a_buffer.read(isArray)) {
369  _clear();
370  return false;
371  }
372  if(isArray) {
373  if(!a_buffer.read_fast_array<int>(fBasketEntry,fMaxBaskets)) {
374  _clear();
375  return false;
376  }
377  }}
378 
379  //Seek_t[fMaxBaskets]
380  {char isBigFile;
381  if(!a_buffer.read(isBigFile)) {
382  _clear();
383  return false;
384  }
385  if(isBigFile==2) {
386  if(!a_buffer.read_fast_array<seek>(fBasketSeek,fMaxBaskets)) {
387  _clear();
388  return false;
389  }
390  } else {
391  for(uint32 i=0;i<fMaxBaskets;i++) {
392  seek32 _s;
393  if(!a_buffer.read(_s)) {
394  _clear();
395  return false;
396  }
397  fBasketSeek[i] = _s;
398  }
399  }}
400 
401  } else { //vers>=10
402  // See TStreamerInfo::ReadBuffer::ReadBasicPointer
403 
404  //Int_t[fMaxBaskets]
405  {char isArray;
406  if(!a_buffer.read(isArray)) {
407  _clear();
408  return false;
409  }
410  if(isArray) {
411  if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
412  _clear();
413  return false;
414  }
415  }}
416 
417  //Long64_t[fMaxBaskets]
418  {char isArray;
419  if(!a_buffer.read(isArray)) {
420  _clear();
421  return false;
422  }
423  if(isArray) {
424  uint64* v = new uint64[fMaxBaskets];
425  if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
426  _clear();
427  return false;
428  }
429  for(uint32 i=0;i<fMaxBaskets;i++) fBasketEntry[i] = int(v[i]);
430  delete [] v;
431  }}
432 
433  //Long64_t[fMaxBaskets]
434  {char isArray;
435  if(!a_buffer.read(isArray)) {
436  _clear();
437  return false;
438  }
439  if(isArray) {
440  uint64* v = new uint64[fMaxBaskets];
441  if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
442  _clear();
443  return false;
444  }
445  for(uint32 i=0;i<fMaxBaskets;i++) fBasketSeek[i] = v[i];
446  delete [] v;
447  }}
448  }
449 
450  if(vers>2) {
451  //TString
452  std::string fileName;
453  if(!a_buffer.read(fileName)) {
454  _clear();
455  return false;
456  }
457  }
458 
459  //FIXME if(vers<4) SetAutoDelete(kTRUE);
460  //FIXME gROOT->SetReadingObject(kFALSE);
461  if(!a_buffer.check_byte_count(s, c,"TBranch")) {
462  _clear();
463  return false;
464  }
465 
466  //GB : analyse fBasketEntry.
467  m_first_last.clear();
468  {// There are (m_write_basket+1) sensitive elements in fBasketEntry :
469  // (Do we have to check that ?)
470  for(uint32 i=0;i<m_write_basket;i++) {
471  uint64 first = fBasketEntry[i];
472  uint64 last = fBasketEntry[i+1]-1;
473  m_first_last.push_back(std::pair<uint64,uint64>(first,last));
474  }
475  if(m_entry_number) {
477  uint64 last = m_entry_number-1;
478  m_first_last.push_back(std::pair<uint64,uint64>(first,last));
479  }}
480  //_dump_first_last();
481 
482  //GB : analyse fBasketSeek :
483  {uint32 num = 0;
484  uint32 mxi = 0;
485  for(uint32 i=0;i<fMaxBaskets;i++) {
486  if(!fBasketSeek[i]) continue;
487  num++;
488  mxi = mx<uint32>(i,mxi);
489  }
490  if(m_write_basket) {
491  if((num!=m_write_basket)||(mxi!=(m_write_basket-1))) {
492  m_out << "tools::rroot::branch::stream :"
493  << " fBasketSeek[] inconsistent with m_write_basket."
494  << " m_write_basket " << m_write_basket
495  << " num " << num
496  << " mxi " << mxi
497  << std::endl;
498  _clear();
499  return false;
500  }
501  }}
502 
503  //GB : analyse m_streamed_baskets :
504  {int index = 0;
506  if(*it) {
507  if(!(*it)->buf()||!(*it)->buf_size()) {
508  m_out << "tools::rroot::branch::stream :"
509  << " expect a basket with a not empty buffer."
510  << std::endl;
511  return false;
512  }
513  //in the below, false is to say m_baskets is not owner of *it.
514  m_baskets[index] = std::pair<basket*,bool>(*it,false);
515  }
516  index++;
517  }}
518 
519  return true;
520  }
521 
522 public:
523  //virtual for branch_element
524 
525  virtual bool read_leaves(ifile&,buffer& a_buffer){
527  if(!(*it)->read_buffer(a_buffer)) {
528  m_out << "tools::rroot::branch::read_leaves :"
529  << " read_buffer failed."
530  << std::endl;
531  return false;
532  }
533  }
534  return true;
535  }
536 
537  virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
538  // Read all leaves of entry and return total number of bytes :
539  // The input argument entry is the entry serial number in the current tree.
540  a_nbytes = 0;
541  //if(_test_bit(kDoNotProcess())) return true;
542 
543  //if(fReadEntry == (int)a_entry) return true;
544  if(a_entry>=m_entry_number) {
545  //m_out << "tools::rroot::branch::find_entry :"
546  // << " for branch " << sout(m_name) << " :"
547  // << " a_entry not within [0," << m_entry_number << "[."
548  // << std::endl;
549  //return false;
550  return true; //CERN-ROOT does not consider it is an error.
551  }
552  if(!m_entry_number || m_first_last.empty() ) { //GB
553  m_out << "tools::rroot::branch::find_entry :"
554  << " nothing to read."
555  << std::endl;
556  return false; //nothing to read.
557  }
558 
559  if(m_read_basket>=m_first_last.size()) {
560  m_out << "tools::rroot::branch::find_entry :"
561  << " bad m_first_last access."
562  << std::endl;
563  return false;
564  }
565 
566  uint64 first = m_first_last[m_read_basket].first;
567  uint64 last = m_first_last[m_read_basket].second;
568 
569  // Are we still in the same ReadBasket?
570  if((a_entry<first)||(a_entry>last)) {
571  m__read_basket = 0;
572  uint32 old_read_basket = m_read_basket;
573 
574  //look first in the next basket window :
575  bool found = false;
576  if((m_read_basket+1)<m_first_last.size()) {
577  first = m_first_last[m_read_basket+1].first;
578  last = m_first_last[m_read_basket+1].second;
579  if((a_entry>=first)&&(a_entry<=last)) {
580  m_read_basket++;
581  found = true;
582  }
583  }
584  if(!found) {
585  uint32 count = 0;
586  typedef std::pair<uint64,uint64> first_last;
587  tools_vforcit(first_last,m_first_last,it) {
588  first = (*it).first;
589  last = (*it).second;
590  if((a_entry>=first)&&(a_entry<=last)) {
591  m_read_basket = count;
592  found = true;
593  break;
594  }
595  count++;
596  }
597  }
598  if(!found) { //something weird in fBasketEntry.
599  m_out << "tools::rroot::branch::find_entry :"
600  << " fancy fBasketEntry."
601  << std::endl;
602  return false;
603  } else {
604  // if found, erase m_baskets[old_read_basket] to avoid
605  // having all data in memory !
606  std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(old_read_basket);
607  if(it!=m_baskets.end()) {
608  if((*it).second.second) {
609  basket* bsk = (*it).second.first;
610  m_baskets.erase(it);
611  delete bsk;
612  //::printf("debug : erase basket %d\n",old_read_basket);
613  }
614  }
615  }
616  }
617 
618  if(!m__read_basket) {
619 
620  basket* bsk = 0;
621  std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(m_read_basket);
622  if(it!=m_baskets.end()) {
623  bsk = (*it).second.first;
624  } else {
626  m_out << "tools::rroot::branch::find_entry :"
627  << " basket lacking !"
628  << " wanting index " << m_read_basket
629  << ". fBasketSeek entries " << m_write_basket
630  << std::endl;
631  return false;
632  }
633  if(!fBasketSeek[m_read_basket]) {
634  m_out << "tools::rroot::branch::find_entry :"
635  << " fBasketSeek is null for index " << m_read_basket
636  << std::endl;
637  return false;
638  }
640  m_out << "tools::rroot::branch::find_entry :"
641  << " fBasketBytes is null for index " << m_read_basket
642  << std::endl;
643  return false;
644  }
645 
647  if(!bsk) {
648  m_out << "tools::rroot::branch::find_entry :"
649  << " can't read basket " << m_read_basket
650  << " at file pos " << fBasketSeek[m_read_basket]
651  << " and size " << fBasketBytes[m_read_basket]
652  << std::endl;
653  return false;
654  }
655 
656  //m_out << "tools::rroot::branch::find_entry :"
657  // << " got basket " << m_read_basket
658  // << " of size " << fBasketBytes[m_read_basket]
659  // << std::endl;
660 
661  m_baskets[m_read_basket] = std::pair<basket*,bool>(bsk,true);
662  }
663 
664  m__read_basket = bsk;
665  }
666 
667  // Set entry offset in buffer and read data from all leaves
668  //buf->resetMap();
669 
670  uint32 bufbegin;
671  {int* entry_offset = m__read_basket->entry_offset();
672  if(entry_offset) {
673  uint32 index = uint32(a_entry-first);
674  if(index>=m__read_basket->nev()) {
675  m_out << "tools::rroot::branch::find_entry :"
676  << " can't access entry offset " << index
677  << ". nev " << m__read_basket->nev()
678  << std::endl;
679  return false;
680  }
681  bufbegin = entry_offset[index];
682  //::printf("debug : xxx++ %u : %u\n",index,bufbegin);
683  } else {
684  bufbegin = (uint32)(m__read_basket->key_length() + (a_entry-first)*m__read_basket->nev_buf_size());
685  }}
686 
687  {int* displacement = m__read_basket->displacement();
688  if(displacement) {
689  m_out << "tools::rroot::branch::find_entry :"
690  << " not null displacement. Not yet handled."
691  << std::endl;
692  //buf->setDisplacement(displacement[a_entry-first]);
693  } else {
694  //buf->setDisplacement();
695  }}
696 
697 /*
698  if(bufbegin>=m__read_basket->buf_size()) {
699  m_out << "tools::rroot::branch::find_entry :"
700  << " bad buffer access for entry " << a_entry
701  << ". bufbegin " << bufbegin
702  << ", buf_size " << basket->buf_size()
703  << ", (entry-first) " << (a_entry-first)
704  << std::endl;
705  {int* entry_offset = m__read_basket->entry_offset();
706  if(entry_offset) {
707  uint32 nev = m__read_basket->nev();
708  ::printf("debug : eoff : num %d\n",nev);
709  for(uint32 i=0;i<nev;i++){
710  ::printf("debug : eoff %d : %d\n",i,entry_offset[i]);
711  }
712  }}
713  return false;
714  }
715 */
716 
717  buffer _buffer(m_out,a_file.byte_swap(),m__read_basket->buf_size(),m__read_basket->buf(),0,false);
718  _buffer.set_offset(bufbegin);
719  _buffer.set_map_objs(true); //for MEMPHYS/applications/read.icc
720 
721  if(!read_leaves(a_file,_buffer)) {
722  m_out << "tools::rroot::branch::find_entry :"
723  << " can't read leaves for entry " << a_entry
724  << ". read_basket was " << m_read_basket
725  << ", first " << first
726  << ", last " << last
727  << "."
728  << std::endl;
729  return false;
730  }
731 
732  //fReadEntry = a_entry;
733 
734  a_nbytes = _buffer.length() - bufbegin;
735 
736  return true;
737  }
738 
739  virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry) {
740  // Print values of all active leaves for entry :
741  // if entry==-1, print current entry (default)
742  uint32 n;
743  if(!find_entry(a_file,a_entry,n)) return false;
744 
746  base_leaf* bl = *it;
747 
748  uint32 num = bl->num_elem();
749  num = mn<uint32>(num,10);
750  if(!num) continue;
751 
752  {std::string s;
753  uint32 len = uint32(bl->name().size())+128;
754  sprintf(s,len," %-15s = ",bl->name().c_str());
755  a_out << s;}
756 
757  for(uint32 i=0;i<num;i++) {
758  if(i) a_out << ", ";
759  bl->print_value(a_out,i);
760  }
761 
762  a_out << std::endl;
763  }
764 
765  return true;
766  }
767 public:
768  branch(std::ostream& a_out,ifac& a_fac)
769  :m_out(a_out)
770  ,m_fac(a_fac)
771 
773  ,m__read_basket(0)
774 
775  //,m_bits(0)
776  ,m_name("")
777  ,m_title("")
778  ,fAutoDelete(false)
779 
780  ,m_branches(m_fac)
781  ,m_leaves(m_fac)
782 
783  ,fEntryOffsetLen(0)
784  ,m_write_basket(0)
785  ,m_entry_number(0)
786  ,m_read_basket(0)
787  ,fBasketBytes(0)
788  ,fBasketEntry(0)
789  ,fBasketSeek(0)
790  {
791 #ifdef TOOLS_MEM
792  mem::increment(s_class().c_str());
793 #endif
794  }
795  virtual ~branch(){
796  _clear();
797 #ifdef TOOLS_MEM
798  mem::decrement(s_class().c_str());
799 #endif
800  }
801 protected:
802  branch(const branch& a_from)
803  :iro(a_from)
804  ,m_out(a_from.m_out),m_fac(a_from.m_fac)
806  ,m__read_basket(0)
807  ,fAutoDelete(false)
808  ,m_branches(m_fac)
809  ,m_leaves(m_fac)
810  ,fEntryOffsetLen(1000)
811  ,m_write_basket(0)
812  ,m_entry_number(0)
813  ,m_read_basket(0)
814  ,fBasketBytes(0)
815  ,fBasketEntry(0)
816  ,fBasketSeek(0)
817  {}
818  branch& operator=(const branch&){return *this;}
819 public:
821  const std::string& name() const {return m_name;}
822  const std::string& title() const {return m_title;}
823  const std::vector<base_leaf*>& leaves() const {return m_leaves;}
824  const std::vector<branch*>& branches() const {return m_branches;}
825 protected:
826  basket* get_basket(ifile& a_file,seek a_pos,uint32 a_len) {
827  //if(fBranch.tree().memoryFull(fBufferSize)) fBranch.dropBaskets();
828  if(!a_len) return 0;
829 
830  basket* _basket = new basket(m_out,a_pos,a_len); //basket is a key.
831  if(!_basket->read_file(a_file)) {
832  m_out << "tools::rroot::branch::get_basket :"
833  << " read_file() failed."
834  << std::endl;
835  delete _basket;
836  return 0;
837  }
838  {buffer _buffer(m_out,a_file.byte_swap(),a_len,_basket->buf(),0,false);
839  if(!_basket->stream(_buffer)) {
840  m_out << "tools::rroot::branch::get_basket :"
841  << " basket stream failed."
842  << std::endl;
843  delete _basket;
844  return 0;
845  }}
846  unsigned int sz;
847  char* buf = _basket->get_object_buffer(a_file,sz); //basket owns buf.
848  if(!buf) {
849  m_out << "tools::rroot::branch::get_basket :"
850  << " get_object_buffer() failed."
851  << std::endl;
852  delete _basket;
853  return 0;
854  }
855 
856  if(_basket->seek_key()!=a_pos) { //consistency check.
857  m_out << "tools::rroot::branch::get_basket :"
858  << " seek anomaly."
859  << " a_pos " << a_pos
860  << " seek_key() " << _basket->seek_key()
861  << std::endl;
862  delete _basket;
863  return 0;
864  }
865  //if(_basket->nbytes()!=a_len) { //consistency check.
866  // m_out << "tools::rroot::branch::get_basket :"
867  // << " WARNING : length anomaly."
868  // << " a_len " << a_len
869  // << " nbytes() " << _basket->nbytes()
870  // << std::endl;
871  //}
872 
873  if(fEntryOffsetLen) {
874  if(!_basket->read_offset_tables(a_file.byte_swap())) {
875  m_out << "tools::rroot::branch::get_basket :"
876  << " read_offset_tables failed."
877  << std::endl;
878  delete _basket;
879  return 0;
880  }}
881 
882  return _basket;
883  }
884 protected:
885  void _clear() {
886  delete [] fBasketEntry;
887  delete [] fBasketBytes;
888  delete [] fBasketSeek;
889  fBasketEntry = 0;
890  fBasketBytes = 0;
891  fBasketSeek = 0;
892 
893  {typedef std::pair<basket*,bool> basket_todel;
894  tools_mforit(uint32,basket_todel,m_baskets,it) {
895  if((*it).second.second) delete (*it).second.first;
896  }
897  m_baskets.clear();}
898 
899  m_branches.cleanup();
900  m_leaves.cleanup();
901  m_streamed_baskets.cleanup();
902  }
903 
905  m_out << "tools::rroot::branch::_dump_first_last :"
906  << " first_last " << m_first_last.size()
907  << std::endl;
908  typedef std::pair<uint64,uint64> first_last;
909  tools_vforcit(first_last,m_first_last,it) {
910  uint64 first = (*it).first;
911  uint64 last = (*it).second;
912  m_out << "tools::rroot::branch::stream :"
913  << " first " << first
914  << " last " << last
915  << std::endl;
916  }
917  }
918 
919  //bool _test_bit(uint32 a_f) const {
920  // return (bool)(m_bits & a_f);
921  //}
922 
923 
924 protected:
925  std::ostream& m_out;
927  std::vector< std::pair<uint64,uint64> > m_first_last;
928  std::map<uint32, std::pair<basket*,bool> > m_baskets;
930  basket* m__read_basket; //optimization
931 protected:
932  //Object
933  //uint32 m_bits;
934  //Named
935  std::string m_name;
936  std::string m_title;
937 
941  uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers
942  uint32 m_write_basket; // Last basket number written
943  uint32 m_entry_number; // Current entry number (last one filled in this branch)
945  int* fBasketBytes; //[fMaxBaskets] Length of baskets on file
946  int* fBasketEntry; //[fMaxBaskets] Table of first entry in eack basket
947  seek* fBasketSeek; //[fMaxBaskets] Addresses of baskets on file
948 };
949 
950 }}
951 
952 #endif
tools::rroot::branch::id_class
static cid id_class()
Definition: branch:37
tools::uint64
unsigned long long uint64
Definition: typedefs:72
tools::rroot::branch::m_baskets
std::map< uint32, std::pair< basket *, bool > > m_baskets
Definition: branch:928
tools::rroot::branch::m_out
std::ostream & m_out
Definition: branch:925
tools::rroot::branch::read_leaves
virtual bool read_leaves(ifile &, buffer &a_buffer)
Definition: branch:525
tools::rroot::branch::fEntryOffsetLen
uint32 fEntryOffsetLen
Definition: branch:941
tools::rroot::branch::m_name
std::string m_name
Definition: branch:935
tools::rroot::key::seek_key
seek seek_key() const
Definition: key:179
tools::rroot::basket::read_offset_tables
bool read_offset_tables(bool a_byte_swap)
Definition: basket:298
tools::rroot::seek32
int seek32
Definition: seek:17
tools::rroot::branch::cast
virtual void * cast(const std::string &a_class) const
Definition: branch:31
tools::rroot::branch::m_streamed_baskets
obj_array< basket > m_streamed_baskets
Definition: branch:929
tools::rroot::Object_stream
bool Object_stream(buffer &a_buffer, uint32 &a_id, uint32 &a_bits)
Definition: object:12
tools::rroot::rbuf::read_fast_array
bool read_fast_array(bool *b, uint32 n)
Definition: rbuf:261
tools::rroot::branch::cast
virtual void * cast(cid a_class) const
Definition: branch:38
tools::rroot::branch
Definition: branch:23
dummy
tools::rroot::key::buf_size
uint32 buf_size() const
Definition: key:203
tools::rroot::base_leaf::print_value
virtual bool print_value(std::ostream &, uint32) const =0
tools::rroot::buffer::check_byte_count
bool check_byte_count(uint32 a_start_pos, uint32 a_byte_count, const std::string &a_store_cls)
Definition: buffer:568
tools_mforit
#define tools_mforit(a__K, a__V, a__m, a__it)
Definition: forit:52
tools::rroot::branch::branch
branch(const branch &a_from)
Definition: branch:802
tools::rroot::branch::m__read_basket
basket * m__read_basket
Definition: branch:930
tools::rroot::branch::~branch
virtual ~branch()
Definition: branch:795
ifile
tools::rroot::branch::fBasketEntry
int * fBasketEntry
Definition: branch:946
tools::rroot::basket::stream
virtual bool stream(buffer &a_buffer)
Definition: basket:39
tools::rroot::branch::m_write_basket
uint32 m_write_basket
Definition: branch:942
tools::rroot::base_leaf::name
const std::string & name() const
Definition: base_leaf:146
tools::rroot::branch::leaves
const std::vector< base_leaf * > & leaves() const
Definition: branch:823
tools::rroot::branch::entry_number
uint32 entry_number() const
Definition: branch:820
tools::rroot::branch::m_read_basket
uint32 m_read_basket
Definition: branch:944
tools::rroot::Named_stream
bool Named_stream(buffer &a_buffer, std::string &a_name, std::string &a_title)
Definition: named:15
tools::rroot::branch::m_first_last
std::vector< std::pair< uint64, uint64 > > m_first_last
Definition: branch:927
tools::rroot::dummy
Definition: dummy:22
tools::rroot::base_leaf::num_elem
virtual uint32 num_elem() const =0
tools::rroot::rbuf::read_array
bool read_array(uint32 a_sz, T *&a_a, uint32 &a_n)
Definition: rbuf:314
obj_array
tools::rroot::branch::_clear
void _clear()
Definition: branch:885
tools::rroot::key::get_object_buffer
char * get_object_buffer(ifile &a_file, uint32 &a_size)
Definition: key:267
tools::rroot::branch::m_entry_number
uint32 m_entry_number
Definition: branch:943
tools::rroot::branch::fBasketBytes
int * fBasketBytes
Current basket number when reading.
Definition: branch:945
tools::rroot::key::buf
char * buf() const
Definition: key:200
tools::rroot::buffer::read_version
bool read_version(short &a_version)
Definition: buffer:503
tools::args
Definition: args:24
tools::rroot::base_leaf
Definition: base_leaf:16
tools::rroot::AttFill_stream
bool AttFill_stream(buffer &a_buffer, short &a_color, short &a_style)
Definition: named:38
tools::rroot::basket::displacement
int * displacement()
Definition: basket:293
tools::rroot::branch::m_leaves
obj_array< base_leaf > m_leaves
Definition: branch:940
tools::rroot::branch::get_basket
basket * get_basket(ifile &a_file, seek a_pos, uint32 a_len)
Definition: branch:826
tools::rroot::seek
int64 seek
Definition: seek:16
tools::rroot::branch::m_title
std::string m_title
Definition: branch:936
tools::rroot::branch_cid
cid branch_cid()
Definition: cids:24
tools::rroot::buffer::length
uint32 length() const
Definition: buffer:120
tools::rroot::branch::find_entry
virtual bool find_entry(ifile &a_file, uint64 a_entry, uint32 &a_nbytes)
Definition: branch:537
tools::rroot::branch::fAutoDelete
bool fAutoDelete
Definition: branch:938
tools::rroot::branch::operator=
branch & operator=(const branch &)
Definition: branch:818
basket
tools::rroot::branch::m_fac
ifac & m_fac
Definition: branch:926
tools::rroot::branch::branches
const std::vector< branch * > & branches() const
Definition: branch:824
tools::rroot::basket::nev_buf_size
uint32 nev_buf_size() const
Definition: basket:294
tools::rroot::buffer::set_map_objs
void set_map_objs(bool a_value)
Definition: buffer:123
tools::rroot::basket::entry_offset
int * entry_offset()
Definition: basket:292
tools::rroot::ifac
Definition: ifac:19
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::rroot::ifile
Definition: ifile:16
tools::rroot::buffer::set_offset
void set_offset(unsigned int a_off)
Definition: buffer:117
tools::rroot::branch::stream
virtual bool stream(buffer &a_buffer)
Definition: branch:44
tools::rroot::branch::branch
branch(std::ostream &a_out, ifac &a_fac)
Definition: branch:768
tools::rroot::basket
Definition: basket:17
tools::rroot::branch::title
const std::string & title() const
Definition: branch:822
tools::rroot::buffer
Definition: buffer:43
seek
tools::rroot::key::key_length
uint32 key_length() const
Definition: key:204
tools::sprintf
bool sprintf(std::string &a_string, int a_length, const char *a_format,...)
Definition: sprintf:34
tools::file::found
bool found(const std::string &a_file, const std::string &a_what, std::vector< std::string > &a_found)
Definition: file:507
tools::rroot::ifile::byte_swap
virtual bool byte_swap() const =0
tools::rroot::basket::nev
uint32 nev() const
Definition: basket:295
tools::rroot::rbuf::read
bool read(unsigned char &a_x)
Definition: rbuf:146
tools::rroot::branch::name
const std::string & name() const
Definition: branch:821
tools::rroot::branch::s_cls
virtual const std::string & s_cls() const
Definition: branch:35
tools::rroot::branch::m_branches
obj_array< branch > m_branches
Definition: branch:939
tools::rroot::dummy::stream
virtual bool stream(buffer &a_buffer)
Definition: dummy:42
tools::rroot::iro
Definition: iro:19
tools::rroot::ifac::args
std::map< char, void * > args
Definition: ifac:21
tools_vforcit
#define tools_vforcit(a__T, a__v, a__it)
Definition: forit:7
tools::rroot::branch::fBasketSeek
seek * fBasketSeek
Definition: branch:947
tools::rroot::branch::_dump_first_last
void _dump_first_last()
Definition: branch:904
tools::uint32
unsigned int uint32
Definition: typedefs:71
tools::rroot::branch::show
virtual bool show(std::ostream &a_out, ifile &a_file, uint64 a_entry)
Definition: branch:739
tools::rroot::branch::copy
virtual iro * copy() const
Definition: branch:43
tools::rroot::branch::s_class
static const std::string & s_class()
Definition: branch:26
base_leaf
tools::rroot::obj_array
Definition: obj_array:17
tools::cid
unsigned short cid
Definition: cid:9
tools::rroot::key::read_file
bool read_file(ifile &a_file)
Definition: key:186
ifac