Warning, /include/Geant4/tools/rroot/branch is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_rroot_branch
0005 #define tools_rroot_branch
0006
0007 #include "base_leaf"
0008 #include "basket"
0009 #include "obj_array"
0010 #include "seek"
0011 #include "ifile"
0012 #include "ifac"
0013 #include "../mnmx"
0014 #include "../forit"
0015 #include "../sprintf"
0016 #include "dummy" //for TIOFeatures streaming.
0017
0018 #include <map>
0019
0020 namespace tools {
0021 namespace rroot {
0022
0023 class branch : public virtual iro {
0024 //static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches
0025 public:
0026 static const std::string& s_class() {
0027 static const std::string s_v("tools::rroot::branch");
0028 return s_v;
0029 }
0030 public: //iro
0031 virtual void* cast(const std::string& a_class) const {
0032 if(void* p = cmp_cast<branch>(this,a_class)) return p;
0033 return 0;
0034 }
0035 virtual const std::string& s_cls() const {return s_class();}
0036 public:
0037 static cid id_class() {return branch_cid();}
0038 virtual void* cast(cid a_class) const {
0039 if(void* p = cmp_cast<branch>(this,a_class)) {return p;}
0040 else return 0;
0041 }
0042 public:
0043 virtual iro* copy() const {return new branch(*this);}
0044 virtual bool stream(buffer& a_buffer) {
0045 _clear();
0046 //::printf("debug : branch::stream : begin\n");
0047
0048 int fCompress;
0049 int fBasketSize;
0050 //int fNleaves;
0051 //uint64 m_entries;
0052
0053 //uint64 m_tot_bytes;
0054 //uint64 m_zip_bytes;
0055 int fSplitLevel;
0056 uint32 fMaxBaskets;
0057 int fOffset;
0058
0059 unsigned int _s,_c;
0060 //FIXME gROOT->SetReadingObject(kTRUE);
0061 short vers;
0062 if(!a_buffer.read_version(vers,_s,_c)) return false;
0063
0064 //::printf("debug : branch::stream : version %d count %d\n",vers,c);
0065
0066 if (vers > 5) {
0067 //TBranch::Class()->ReadBuffer(b, this, v, s, c);
0068 //gBranch = branchSave;
0069 //fDirectory = gDirectory;
0070 //fNleaves = m_leaves.GetEntriesFast();
0071 //if (fFileName.Length() != 0) fDirectory = 0;
0072 //gROOT->SetReadingObject(kFALSE);
0073 //return;
0074 }
0075 //====process old versions before automatic schema evolution
0076
0077 {uint32 old = a_buffer.length();
0078 uint32 id;
0079 uint32 m_bits;
0080 if(!Object_stream(a_buffer,id,m_bits)) return false;
0081 a_buffer.set_offset(old);}
0082
0083 if(!Named_stream(a_buffer,m_name,m_title)) return false;
0084
0085 //::printf("debug : branch::stream %s %s\n",m_name.c_str(),m_title.c_str());
0086
0087 if(vers<=5) {
0088 if(!a_buffer.read(fCompress)) return false;
0089 if(!a_buffer.read(fBasketSize)) return false;
0090 if(!a_buffer.read(fEntryOffsetLen)) return false;
0091 if(!a_buffer.read(fMaxBaskets)) return false;
0092 if(!a_buffer.read(m_write_basket)) return false;
0093 if(!a_buffer.read(m_entry_number)) return false;
0094 {double v;
0095 if(!a_buffer.read(v)) return false;
0096 //m_entries = uint64(v);
0097 }
0098 {double v;
0099 if(!a_buffer.read(v)) return false;
0100 //m_tot_bytes = uint64(v);
0101 }
0102 {double v;
0103 if(!a_buffer.read(v)) return false;
0104 //m_zip_bytes = uint64(v);
0105 }
0106 if(!a_buffer.read(fOffset)) return false;
0107
0108 } else if(vers<=6) {
0109 if(!a_buffer.read(fCompress)) return false;
0110 if(!a_buffer.read(fBasketSize)) return false;
0111 if(!a_buffer.read(fEntryOffsetLen)) return false;
0112 if(!a_buffer.read(m_write_basket)) return false;
0113 if(!a_buffer.read(m_entry_number)) return false;
0114 if(!a_buffer.read(fOffset)) return false;
0115 if(!a_buffer.read(fMaxBaskets)) return false;
0116 {double v;
0117 if(!a_buffer.read(v)) return false;
0118 //m_entries = uint64(v);
0119 }
0120 {double v;
0121 if(!a_buffer.read(v)) return false;
0122 //m_tot_bytes = uint64(v);
0123 }
0124 {double v;
0125 if(!a_buffer.read(v)) return false;
0126 //m_zip_bytes = uint64(v);
0127 }
0128
0129 } else if(vers<=7) {
0130 if(!a_buffer.read(fCompress)) return false;
0131 if(!a_buffer.read(fBasketSize)) return false;
0132 if(!a_buffer.read(fEntryOffsetLen)) return false;
0133 if(!a_buffer.read(m_write_basket)) return false;
0134 if(!a_buffer.read(m_entry_number)) return false;
0135 if(!a_buffer.read(fOffset)) return false;
0136 if(!a_buffer.read(fMaxBaskets)) return false;
0137 if(!a_buffer.read(fSplitLevel)) return false;
0138 {double v;
0139 if(!a_buffer.read(v)) return false;
0140 //m_entries = uint64(v);
0141 }
0142 {double v;
0143 if(!a_buffer.read(v)) return false;
0144 //m_tot_bytes = uint64(v);
0145 }
0146 {double v;
0147 if(!a_buffer.read(v)) return false;
0148 //m_zip_bytes = uint64(v);
0149 }
0150
0151 } else if(vers<=9) {
0152 {short color,style;
0153 if(!AttFill_stream(a_buffer,color,style)) return false;}
0154 if(!a_buffer.read(fCompress)) return false;
0155 if(!a_buffer.read(fBasketSize)) return false;
0156 if(!a_buffer.read(fEntryOffsetLen)) return false;
0157 if(!a_buffer.read(m_write_basket)) return false;
0158 if(!a_buffer.read(m_entry_number)) return false;
0159 if(!a_buffer.read(fOffset)) return false;
0160 if(!a_buffer.read(fMaxBaskets)) return false;
0161 if(!a_buffer.read(fSplitLevel)) return false;
0162 {double v;
0163 if(!a_buffer.read(v)) return false;
0164 //m_entries = uint64(v);
0165 }
0166 {double v;
0167 if(!a_buffer.read(v)) return false;
0168 //m_tot_bytes = uint64(v);
0169 }
0170 {double v;
0171 if(!a_buffer.read(v)) return false;
0172 //m_zip_bytes = uint64(v);
0173 }
0174
0175 } else if(vers<=10) {
0176 {short color,style;
0177 if(!AttFill_stream(a_buffer,color,style)) return false;}
0178
0179 if(!a_buffer.read(fCompress)) return false;
0180 if(!a_buffer.read(fBasketSize)) return false;
0181 if(!a_buffer.read(fEntryOffsetLen)) return false;
0182 if(!a_buffer.read(m_write_basket)) return false;
0183 {uint64 v;
0184 if(!a_buffer.read(v)) return false;
0185 m_entry_number = uint32(v);}
0186 if(!a_buffer.read(fOffset)) return false;
0187 if(!a_buffer.read(fMaxBaskets)) return false;
0188 if(!a_buffer.read(fSplitLevel)) return false;
0189
0190 {uint64 v;
0191 if(!a_buffer.read(v)) return false;
0192 //m_entries = v;
0193 }
0194 {uint64 v;
0195 if(!a_buffer.read(v)) return false;
0196 //m_tot_bytes = v;
0197 }
0198 {uint64 v;
0199 if(!a_buffer.read(v)) return false;
0200 //m_zip_bytes = v;
0201 }
0202
0203 } else { //vers>=11
0204
0205 {short color,style;
0206 if(!AttFill_stream(a_buffer,color,style)) return false;}
0207
0208 if(!a_buffer.read(fCompress)) return false;
0209 if(!a_buffer.read(fBasketSize)) return false;
0210 if(!a_buffer.read(fEntryOffsetLen)) return false;
0211 if(!a_buffer.read(m_write_basket)) return false;
0212 {uint64 v;
0213 if(!a_buffer.read(v)) return false;
0214 m_entry_number = uint32(v);}
0215 if(vers>=13) {
0216 dummy _dummy;
0217 if(!_dummy.stream(a_buffer)) { //TIOFeatures fIOFeatures
0218 m_out << "tools::rroot::branch::stream : can't read (dummy) TIOFeatures." << std::endl;
0219 return false;
0220 }
0221 }
0222 if(!a_buffer.read(fOffset)) return false;
0223 if(!a_buffer.read(fMaxBaskets)) return false;
0224 if(!a_buffer.read(fSplitLevel)) return false;
0225 {uint64 v;
0226 if(!a_buffer.read(v)) return false;
0227 //m_entries = v;
0228 }
0229 {uint64 v;
0230 if(!a_buffer.read(v)) return false;} //fFirstEntry
0231 {uint64 v;
0232 if(!a_buffer.read(v)) return false;
0233 //m_tot_bytes = v;
0234 }
0235 {uint64 v;
0236 if(!a_buffer.read(v)) return false;
0237 //m_zip_bytes = v;
0238 }
0239 }
0240
0241 //::printf("debug : branch::stream : %s : fSplitLevel %d\n",m_name.c_str(),fSplitLevel);
0242
0243 //TObjArray
0244 //::printf("debug : branch::stream : branches : begin\n");
0245 {ifac::args args;
0246 if(!m_branches.stream(a_buffer,args)) {
0247 m_out << "tools::rroot::branch::stream :"
0248 << " can't read branches."
0249 << std::endl;
0250 return false;
0251 }}
0252 //::printf("debug : branch::stream : branches : end %d\n",
0253 // m_branches.size());
0254
0255 /* We see that with LHCb files.
0256 if(m_entry_number!=m_entries) {
0257 m_out << "tools::rroot::branch::stream :"
0258 << " for branch " << sout(m_name) << " :"
0259 << " WARNING : m_entry_number!=m_entries."
0260 << " m_entry_number " << m_entry_number
0261 << " m_entries " << m_entries
0262 << std::endl;
0263 //return false;
0264 }
0265 */
0266
0267 //TObjArray
0268 //::printf("debug : branch::stream : leaves : begin\n");
0269 {ifac::args args;
0270 //args[ifac::arg_branch()] = this;
0271 if(!m_leaves.stream(a_buffer,args)) {
0272 m_out << "tools::rroot::branch::stream :"
0273 << " can't read leaves."
0274 << std::endl;
0275 return false;
0276 }}
0277 //::printf("debug : branch::stream : leaves : end\n");
0278
0279 //TObjArray
0280 //IMPORTANT : accept_null=true
0281 //::printf("debug : branch::stream : streamed_baskets : begin\n");
0282 {ifac::args args;
0283 if(!m_streamed_baskets.stream(a_buffer,args,true)) {
0284 m_out << "tools::rroot::branch::stream :"
0285 << " can't read baskets."
0286 << std::endl;
0287 return false;
0288 }}
0289 //::printf("debug : branch::stream : streamed_baskets : end\n");
0290
0291 //fNleaves = m_leaves.size();
0292
0293 if(fMaxBaskets<=0) {
0294 m_out << "tools::rroot::branch::stream :"
0295 << " fMaxBaskets null."
0296 << std::endl;
0297 return false;
0298 }
0299
0300 fBasketEntry = new int[fMaxBaskets];
0301 fBasketBytes = new int[fMaxBaskets];
0302 fBasketSeek = new seek[fMaxBaskets];
0303 {for(uint32 i=0;i<fMaxBaskets;i++) {
0304 fBasketEntry[i] = 0;
0305 fBasketBytes[i] = 0;
0306 fBasketSeek[i] = 0;
0307 }}
0308
0309 if(vers<6) {
0310 {uint32 n;
0311 if(!a_buffer.read_array<int>(fMaxBaskets,fBasketEntry,n)) {
0312 _clear();
0313 return false;
0314 }}
0315 if(vers<=4) {
0316 for (uint32 i=0;i<fMaxBaskets;i++) fBasketBytes[i] = 0;
0317 } else {
0318 uint32 n;
0319 if(!a_buffer.read_array<int>(fMaxBaskets,fBasketBytes,n)) {
0320 _clear();
0321 return false;
0322 }
0323 }
0324 if(vers<2) {
0325 //GB : comment.
0326 //for(int i=0;i<m_write_basket;i++) {
0327 // fBasketSeek[i] = getBasket(i)->seekKey();
0328 //}
0329 m_out << "tools::rroot::branch::stream :"
0330 << " v < 2. Not (yet) handled."
0331 << std::endl;
0332 _clear();
0333 return false;
0334 } else {
0335 int n;
0336 if(!a_buffer.read(n)) {
0337 _clear();
0338 return false;
0339 }
0340 for(int i=0;i<n;i++) {
0341 seek32 _seek;
0342 if(!a_buffer.read(_seek)) {
0343 _clear();
0344 return false;
0345 }
0346 fBasketSeek[i] = _seek;
0347 }
0348 }
0349
0350 } else if(vers<=9) {
0351 // See TStreamerInfo::ReadBuffer::ReadBasicPointer
0352
0353 //Int_t[fMaxBaskets]
0354 {char isArray;
0355 if(!a_buffer.read(isArray)) {
0356 _clear();
0357 return false;
0358 }
0359 if(isArray) {
0360 if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
0361 _clear();
0362 return false;
0363 }
0364 }}
0365
0366 //Int_t[fMaxBaskets]
0367 {char isArray;
0368 if(!a_buffer.read(isArray)) {
0369 _clear();
0370 return false;
0371 }
0372 if(isArray) {
0373 if(!a_buffer.read_fast_array<int>(fBasketEntry,fMaxBaskets)) {
0374 _clear();
0375 return false;
0376 }
0377 }}
0378
0379 //Seek_t[fMaxBaskets]
0380 {char isBigFile;
0381 if(!a_buffer.read(isBigFile)) {
0382 _clear();
0383 return false;
0384 }
0385 if(isBigFile==2) {
0386 if(!a_buffer.read_fast_array<seek>(fBasketSeek,fMaxBaskets)) {
0387 _clear();
0388 return false;
0389 }
0390 } else {
0391 for(uint32 i=0;i<fMaxBaskets;i++) {
0392 seek32 _seek;
0393 if(!a_buffer.read(_seek)) {
0394 _clear();
0395 return false;
0396 }
0397 fBasketSeek[i] = _seek;
0398 }
0399 }}
0400
0401 } else { //vers>=10
0402 // See TStreamerInfo::ReadBuffer::ReadBasicPointer
0403
0404 //Int_t[fMaxBaskets]
0405 {char isArray;
0406 if(!a_buffer.read(isArray)) {
0407 _clear();
0408 return false;
0409 }
0410 if(isArray) {
0411 if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) {
0412 _clear();
0413 return false;
0414 }
0415 }}
0416
0417 //Long64_t[fMaxBaskets]
0418 {char isArray;
0419 if(!a_buffer.read(isArray)) {
0420 _clear();
0421 return false;
0422 }
0423 if(isArray) {
0424 uint64* v = new uint64[fMaxBaskets];
0425 if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
0426 _clear();
0427 return false;
0428 }
0429 for(uint32 i=0;i<fMaxBaskets;i++) fBasketEntry[i] = int(v[i]);
0430 delete [] v;
0431 }}
0432
0433 //Long64_t[fMaxBaskets]
0434 {char isArray;
0435 if(!a_buffer.read(isArray)) {
0436 _clear();
0437 return false;
0438 }
0439 if(isArray) {
0440 uint64* v = new uint64[fMaxBaskets];
0441 if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) {
0442 _clear();
0443 return false;
0444 }
0445 for(uint32 i=0;i<fMaxBaskets;i++) fBasketSeek[i] = v[i];
0446 delete [] v;
0447 }}
0448 }
0449
0450 if(vers>2) {
0451 //TString
0452 std::string fileName;
0453 if(!a_buffer.read(fileName)) {
0454 _clear();
0455 return false;
0456 }
0457 }
0458
0459 //FIXME if(vers<4) SetAutoDelete(kTRUE);
0460 //FIXME gROOT->SetReadingObject(kFALSE);
0461 if(!a_buffer.check_byte_count(_s, _c,"TBranch")) {
0462 _clear();
0463 return false;
0464 }
0465
0466 //GB : analyse fBasketEntry.
0467 m_first_last.clear();
0468 {// There are (m_write_basket+1) sensitive elements in fBasketEntry :
0469 // (Do we have to check that ?)
0470 for(uint32 i=0;i<m_write_basket;i++) {
0471 uint64 first = fBasketEntry[i];
0472 uint64 last = fBasketEntry[i+1]-1;
0473 m_first_last.push_back(std::pair<uint64,uint64>(first,last));
0474 }
0475 if(m_entry_number) {
0476 uint64 first = fBasketEntry[m_write_basket];
0477 uint64 last = m_entry_number-1;
0478 m_first_last.push_back(std::pair<uint64,uint64>(first,last));
0479 }}
0480 //_dump_first_last();
0481
0482 //GB : analyse fBasketSeek :
0483 {uint32 num = 0;
0484 uint32 mxi = 0;
0485 for(uint32 i=0;i<fMaxBaskets;i++) {
0486 if(!fBasketSeek[i]) continue;
0487 num++;
0488 mxi = mx<uint32>(i,mxi);
0489 }
0490 if(m_write_basket) {
0491 if((num!=m_write_basket)||(mxi!=(m_write_basket-1))) {
0492 m_out << "tools::rroot::branch::stream :"
0493 << " fBasketSeek[] inconsistent with m_write_basket."
0494 << " m_write_basket " << m_write_basket
0495 << " num " << num
0496 << " mxi " << mxi
0497 << std::endl;
0498 _clear();
0499 return false;
0500 }
0501 }}
0502
0503 //GB : analyse m_streamed_baskets :
0504 {int index = 0;
0505 tools_vforcit(basket*,m_streamed_baskets,it) {
0506 if(*it) {
0507 if(!(*it)->buf()||!(*it)->buf_size()) {
0508 m_out << "tools::rroot::branch::stream :"
0509 << " expect a basket with a not empty buffer."
0510 << std::endl;
0511 return false;
0512 }
0513 //in the below, false is to say m_baskets is not owner of *it.
0514 m_baskets[index] = std::pair<basket*,bool>(*it,false);
0515 }
0516 index++;
0517 }}
0518
0519 return true;
0520 }
0521
0522 public:
0523 //virtual for branch_element
0524
0525 virtual bool read_leaves(ifile&,buffer& a_buffer){
0526 tools_vforcit(base_leaf*,m_leaves,it) {
0527 if(!(*it)->read_buffer(a_buffer)) {
0528 m_out << "tools::rroot::branch::read_leaves :"
0529 << " read_buffer failed."
0530 << std::endl;
0531 return false;
0532 }
0533 }
0534 return true;
0535 }
0536
0537 virtual bool find_entry(ifile& a_file,uint64 a_entry,uint32& a_nbytes){
0538 // Read all leaves of entry and return total number of bytes :
0539 // The input argument entry is the entry serial number in the current tree.
0540 a_nbytes = 0;
0541 //if(_test_bit(kDoNotProcess())) return true;
0542
0543 //if(fReadEntry == (int)a_entry) return true;
0544 if(a_entry>=m_entry_number) {
0545 //m_out << "tools::rroot::branch::find_entry :"
0546 // << " for branch " << sout(m_name) << " :"
0547 // << " a_entry not within [0," << m_entry_number << "[."
0548 // << std::endl;
0549 //return false;
0550 return true; //CERN-ROOT does not consider it is an error.
0551 }
0552 if(!m_entry_number || m_first_last.empty() ) { //GB
0553 m_out << "tools::rroot::branch::find_entry :"
0554 << " nothing to read."
0555 << std::endl;
0556 return false; //nothing to read.
0557 }
0558
0559 if(m_read_basket>=m_first_last.size()) {
0560 m_out << "tools::rroot::branch::find_entry :"
0561 << " bad m_first_last access."
0562 << std::endl;
0563 return false;
0564 }
0565
0566 uint64 first = m_first_last[m_read_basket].first;
0567 uint64 last = m_first_last[m_read_basket].second;
0568
0569 // Are we still in the same ReadBasket?
0570 if((a_entry<first)||(a_entry>last)) {
0571 m__read_basket = 0;
0572 uint32 old_read_basket = m_read_basket;
0573
0574 //look first in the next basket window :
0575 bool found = false;
0576 if((m_read_basket+1)<m_first_last.size()) {
0577 first = m_first_last[m_read_basket+1].first;
0578 last = m_first_last[m_read_basket+1].second;
0579 if((a_entry>=first)&&(a_entry<=last)) {
0580 m_read_basket++;
0581 found = true;
0582 }
0583 }
0584 if(!found) {
0585 uint32 count = 0;
0586 typedef std::pair<uint64,uint64> first_last;
0587 tools_vforcit(first_last,m_first_last,it) {
0588 first = (*it).first;
0589 last = (*it).second;
0590 if((a_entry>=first)&&(a_entry<=last)) {
0591 m_read_basket = count;
0592 found = true;
0593 break;
0594 }
0595 count++;
0596 }
0597 }
0598 if(!found) { //something weird in fBasketEntry.
0599 m_out << "tools::rroot::branch::find_entry :"
0600 << " fancy fBasketEntry."
0601 << std::endl;
0602 return false;
0603 } else {
0604 // if found, erase m_baskets[old_read_basket] to avoid
0605 // having all data in memory !
0606 std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(old_read_basket);
0607 if(it!=m_baskets.end()) {
0608 if((*it).second.second) {
0609 basket* bsk = (*it).second.first;
0610 m_baskets.erase(it);
0611 delete bsk;
0612 //::printf("debug : erase basket %d\n",old_read_basket);
0613 }
0614 }
0615 }
0616 }
0617
0618 if(!m__read_basket) {
0619
0620 basket* bsk = 0;
0621 std::map<uint32, std::pair<basket*,bool> >::iterator it = m_baskets.find(m_read_basket);
0622 if(it!=m_baskets.end()) {
0623 bsk = (*it).second.first;
0624 } else {
0625 if(m_read_basket>=m_write_basket) {
0626 m_out << "tools::rroot::branch::find_entry :"
0627 << " basket lacking !"
0628 << " wanting index " << m_read_basket
0629 << ". fBasketSeek entries " << m_write_basket
0630 << std::endl;
0631 return false;
0632 }
0633 if(!fBasketSeek[m_read_basket]) {
0634 m_out << "tools::rroot::branch::find_entry :"
0635 << " fBasketSeek is null for index " << m_read_basket
0636 << std::endl;
0637 return false;
0638 }
0639 if(!fBasketBytes[m_read_basket]) {
0640 m_out << "tools::rroot::branch::find_entry :"
0641 << " fBasketBytes is null for index " << m_read_basket
0642 << std::endl;
0643 return false;
0644 }
0645
0646 bsk = get_basket(a_file,fBasketSeek[m_read_basket],fBasketBytes[m_read_basket]);
0647 if(!bsk) {
0648 m_out << "tools::rroot::branch::find_entry :"
0649 << " can't read basket " << m_read_basket
0650 << " at file pos " << fBasketSeek[m_read_basket]
0651 << " and size " << fBasketBytes[m_read_basket]
0652 << std::endl;
0653 return false;
0654 }
0655
0656 //m_out << "tools::rroot::branch::find_entry :"
0657 // << " got basket " << m_read_basket
0658 // << " of size " << fBasketBytes[m_read_basket]
0659 // << std::endl;
0660
0661 m_baskets[m_read_basket] = std::pair<basket*,bool>(bsk,true);
0662 }
0663
0664 m__read_basket = bsk;
0665 }
0666
0667 // Set entry offset in buffer and read data from all leaves
0668 //buf->resetMap();
0669
0670 uint32 bufbegin;
0671 {int* entry_offset = m__read_basket->entry_offset();
0672 if(entry_offset) {
0673 uint32 index = uint32(a_entry-first);
0674 if(index>=m__read_basket->nev()) {
0675 m_out << "tools::rroot::branch::find_entry :"
0676 << " can't access entry offset " << index
0677 << ". nev " << m__read_basket->nev()
0678 << std::endl;
0679 return false;
0680 }
0681 bufbegin = entry_offset[index];
0682 //::printf("debug : xxx++ %u : %u\n",index,bufbegin);
0683 } else {
0684 bufbegin = (uint32)(m__read_basket->key_length() + (a_entry-first)*m__read_basket->nev_buf_size());
0685 }}
0686
0687 {int* displacement = m__read_basket->displacement();
0688 if(displacement) {
0689 m_out << "tools::rroot::branch::find_entry :"
0690 << " not null displacement. Not yet handled."
0691 << std::endl;
0692 //buf->setDisplacement(displacement[a_entry-first]);
0693 } else {
0694 //buf->setDisplacement();
0695 }}
0696
0697 /*
0698 if(bufbegin>=m__read_basket->buf_size()) {
0699 m_out << "tools::rroot::branch::find_entry :"
0700 << " bad buffer access for entry " << a_entry
0701 << ". bufbegin " << bufbegin
0702 << ", buf_size " << basket->buf_size()
0703 << ", (entry-first) " << (a_entry-first)
0704 << std::endl;
0705 {int* entry_offset = m__read_basket->entry_offset();
0706 if(entry_offset) {
0707 uint32 nev = m__read_basket->nev();
0708 ::printf("debug : eoff : num %d\n",nev);
0709 for(uint32 i=0;i<nev;i++){
0710 ::printf("debug : eoff %d : %d\n",i,entry_offset[i]);
0711 }
0712 }}
0713 return false;
0714 }
0715 */
0716
0717 buffer _buffer(m_out,a_file.byte_swap(),m__read_basket->buf_size(),m__read_basket->buf(),0,false);
0718 _buffer.set_offset(bufbegin);
0719 _buffer.set_map_objs(true); //for MEMPHYS/applications/read.icc
0720
0721 if(!read_leaves(a_file,_buffer)) {
0722 m_out << "tools::rroot::branch::find_entry :"
0723 << " can't read leaves for entry " << a_entry
0724 << ". read_basket was " << m_read_basket
0725 << ", first " << first
0726 << ", last " << last
0727 << "."
0728 << std::endl;
0729 return false;
0730 }
0731
0732 //fReadEntry = a_entry;
0733
0734 a_nbytes = _buffer.length() - bufbegin;
0735
0736 return true;
0737 }
0738
0739 virtual bool show(std::ostream& a_out,ifile& a_file,uint64 a_entry) {
0740 // Print values of all active leaves for entry :
0741 // if entry==-1, print current entry (default)
0742 uint32 n;
0743 if(!find_entry(a_file,a_entry,n)) return false;
0744
0745 tools_vforcit(base_leaf*,m_leaves,it) {
0746 base_leaf* bl = *it;
0747
0748 uint32 num = bl->num_elem();
0749 num = mn<uint32>(num,10);
0750 if(!num) continue;
0751
0752 {std::string _s;
0753 uint32 len = uint32(bl->name().size())+128;
0754 sprintf(_s,len," %-15s = ",bl->name().c_str());
0755 a_out << _s;}
0756
0757 for(uint32 i=0;i<num;i++) {
0758 if(i) a_out << ", ";
0759 bl->print_value(a_out,i);
0760 }
0761
0762 a_out << std::endl;
0763 }
0764
0765 return true;
0766 }
0767 public:
0768 branch(std::ostream& a_out,ifac& a_fac)
0769 :m_out(a_out)
0770 ,m_fac(a_fac)
0771
0772 ,m_streamed_baskets(m_fac)
0773 ,m__read_basket(0)
0774
0775 //,m_bits(0)
0776 ,m_name("")
0777 ,m_title("")
0778 ,fAutoDelete(false)
0779
0780 ,m_branches(m_fac)
0781 ,m_leaves(m_fac)
0782
0783 ,fEntryOffsetLen(0)
0784 ,m_write_basket(0)
0785 ,m_entry_number(0)
0786 ,m_read_basket(0)
0787 ,fBasketBytes(0)
0788 ,fBasketEntry(0)
0789 ,fBasketSeek(0)
0790 {
0791 #ifdef TOOLS_MEM
0792 mem::increment(s_class().c_str());
0793 #endif
0794 }
0795 virtual ~branch(){
0796 _clear();
0797 #ifdef TOOLS_MEM
0798 mem::decrement(s_class().c_str());
0799 #endif
0800 }
0801 protected:
0802 branch(const branch& a_from)
0803 :iro(a_from)
0804 ,m_out(a_from.m_out),m_fac(a_from.m_fac)
0805 ,m_streamed_baskets(m_fac)
0806 ,m__read_basket(0)
0807 ,fAutoDelete(false)
0808 ,m_branches(m_fac)
0809 ,m_leaves(m_fac)
0810 ,fEntryOffsetLen(1000)
0811 ,m_write_basket(0)
0812 ,m_entry_number(0)
0813 ,m_read_basket(0)
0814 ,fBasketBytes(0)
0815 ,fBasketEntry(0)
0816 ,fBasketSeek(0)
0817 {}
0818 branch& operator=(const branch&){return *this;}
0819 public:
0820 uint32 entry_number() const {return m_entry_number;}
0821 const std::string& name() const {return m_name;}
0822 const std::string& title() const {return m_title;}
0823 const std::vector<base_leaf*>& leaves() const {return m_leaves;}
0824 const std::vector<branch*>& branches() const {return m_branches;}
0825 protected:
0826 basket* get_basket(ifile& a_file,seek a_pos,uint32 a_len) {
0827 //if(fBranch.tree().memoryFull(fBufferSize)) fBranch.dropBaskets();
0828 if(!a_len) return 0;
0829
0830 basket* _basket = new basket(m_out,a_pos,a_len); //basket is a key.
0831 if(!_basket->read_file(a_file)) {
0832 m_out << "tools::rroot::branch::get_basket :"
0833 << " read_file() failed."
0834 << std::endl;
0835 delete _basket;
0836 return 0;
0837 }
0838 {buffer _buffer(m_out,a_file.byte_swap(),a_len,_basket->buf(),0,false);
0839 if(!_basket->stream(_buffer)) {
0840 m_out << "tools::rroot::branch::get_basket :"
0841 << " basket stream failed."
0842 << std::endl;
0843 delete _basket;
0844 return 0;
0845 }}
0846 unsigned int sz;
0847 char* buf = _basket->get_object_buffer(a_file,sz); //basket owns buf.
0848 if(!buf) {
0849 m_out << "tools::rroot::branch::get_basket :"
0850 << " get_object_buffer() failed."
0851 << std::endl;
0852 delete _basket;
0853 return 0;
0854 }
0855
0856 if(_basket->seek_key()!=a_pos) { //consistency check.
0857 m_out << "tools::rroot::branch::get_basket :"
0858 << " seek anomaly."
0859 << " a_pos " << a_pos
0860 << " seek_key() " << _basket->seek_key()
0861 << std::endl;
0862 delete _basket;
0863 return 0;
0864 }
0865 //if(_basket->nbytes()!=a_len) { //consistency check.
0866 // m_out << "tools::rroot::branch::get_basket :"
0867 // << " WARNING : length anomaly."
0868 // << " a_len " << a_len
0869 // << " nbytes() " << _basket->nbytes()
0870 // << std::endl;
0871 //}
0872
0873 if(fEntryOffsetLen) {
0874 if(!_basket->read_offset_tables(a_file.byte_swap())) {
0875 m_out << "tools::rroot::branch::get_basket :"
0876 << " read_offset_tables failed."
0877 << std::endl;
0878 delete _basket;
0879 return 0;
0880 }}
0881
0882 return _basket;
0883 }
0884 protected:
0885 void _clear() {
0886 delete [] fBasketEntry;
0887 delete [] fBasketBytes;
0888 delete [] fBasketSeek;
0889 fBasketEntry = 0;
0890 fBasketBytes = 0;
0891 fBasketSeek = 0;
0892
0893 {typedef std::pair<basket*,bool> basket_todel;
0894 tools_mforit(uint32,basket_todel,m_baskets,it) {
0895 if((*it).second.second) delete (*it).second.first;
0896 }
0897 m_baskets.clear();}
0898
0899 m_branches.cleanup();
0900 m_leaves.cleanup();
0901 m_streamed_baskets.cleanup();
0902 }
0903
0904 void _dump_first_last() {
0905 m_out << "tools::rroot::branch::_dump_first_last :"
0906 << " first_last " << m_first_last.size()
0907 << std::endl;
0908 typedef std::pair<uint64,uint64> first_last;
0909 tools_vforcit(first_last,m_first_last,it) {
0910 uint64 first = (*it).first;
0911 uint64 last = (*it).second;
0912 m_out << "tools::rroot::branch::stream :"
0913 << " first " << first
0914 << " last " << last
0915 << std::endl;
0916 }
0917 }
0918
0919 //bool _test_bit(uint32 a_f) const {
0920 // return (bool)(m_bits & a_f);
0921 //}
0922
0923
0924 protected:
0925 std::ostream& m_out;
0926 ifac& m_fac;
0927 std::vector< std::pair<uint64,uint64> > m_first_last;
0928 std::map<uint32, std::pair<basket*,bool> > m_baskets;
0929 obj_array<basket> m_streamed_baskets;
0930 basket* m__read_basket; //optimization
0931 protected:
0932 //Object
0933 //uint32 m_bits;
0934 //Named
0935 std::string m_name;
0936 std::string m_title;
0937
0938 bool fAutoDelete;
0939 obj_array<branch> m_branches;
0940 obj_array<base_leaf> m_leaves;
0941 uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers
0942 uint32 m_write_basket; // Last basket number written
0943 uint32 m_entry_number; // Current entry number (last one filled in this branch)
0944 uint32 m_read_basket; //! Current basket number when reading
0945 int* fBasketBytes; //[fMaxBaskets] Length of baskets on file
0946 int* fBasketEntry; //[fMaxBaskets] Table of first entry in eack basket
0947 seek* fBasketSeek; //[fMaxBaskets] Addresses of baskets on file
0948 };
0949
0950 }}
0951
0952 #endif