inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_rroot_branch 00005 #define inlib_rroot_branch 00006 00007 #include "base_leaf" 00008 #include "basket" 00009 #include "named" 00010 #include "seek" 00011 #include "ifile" 00012 #include "ifac" 00013 #include "../mnmx" 00014 00015 #include <map> 00016 00017 namespace inlib { 00018 namespace rroot { 00019 00020 class branch : public virtual iro { 00021 //static uint32 kDoNotProcess() {return (1<<10);} // Active bit for branches 00022 public: 00023 static const std::string& s_class() { 00024 static const std::string s_v("inlib::rroot::branch"); 00025 return s_v; 00026 } 00027 public: //iro 00028 virtual void* cast(const std::string& a_class) const { 00029 if(void* p = inlib::cmp_cast<branch>(this,a_class)) {return p;} 00030 else return 0; 00031 } 00032 virtual bool stream(buffer& a_buffer) { 00033 _clear(); 00034 00035 int fCompress; 00036 int fBasketSize; 00037 int fNleaves; 00038 uint64 m_entries; 00039 00040 uint64 m_tot_bytes; 00041 uint64 m_zip_bytes; 00042 int fSplitLevel; 00043 uint32 fMaxBaskets; 00044 int fOffset; 00045 00046 unsigned int s,c; 00047 //FIXME gROOT->SetReadingObject(kTRUE); 00048 short v; 00049 if(!a_buffer.read_version(v,s,c)) return false; 00050 00051 //::printf("debug : branch::stream : version %d count %d\n",v,c); 00052 00053 if (v > 5) { 00054 //TBranch::Class()->ReadBuffer(b, this, v, s, c); 00055 //gBranch = branchSave; 00056 //fDirectory = gDirectory; 00057 //fNleaves = m_leaves.GetEntriesFast(); 00058 //if (fFileName.Length() != 0) fDirectory = 0; 00059 //gROOT->SetReadingObject(kFALSE); 00060 //return; 00061 } 00062 //====process old versions before automatic schema evolution 00063 00064 {uint32 old = a_buffer.length(); 00065 uint32 id; 00066 uint32 m_bits; 00067 if(!Object_stream(a_buffer,id,m_bits)) return false; 00068 a_buffer.set_offset(old);} 00069 00070 if(!Named_stream(a_buffer,m_name,m_title)) return false; 00071 00072 //::printf("debug : branch::stream %s %s\n", 00073 // m_name.c_str(),m_title.c_str()); 00074 00075 if(v<=5) { 00076 if(!a_buffer.read(fCompress)) return false; 00077 if(!a_buffer.read(fBasketSize)) return false; 00078 if(!a_buffer.read(fEntryOffsetLen)) return false; 00079 if(!a_buffer.read(fMaxBaskets)) return false; 00080 if(!a_buffer.read(m_write_basket)) return false; 00081 if(!a_buffer.read(m_entry_number)) return false; 00082 {double v; 00083 if(!a_buffer.read(v)) return false; 00084 m_entries = uint64(v);} 00085 {double v; 00086 if(!a_buffer.read(v)) return false; 00087 m_tot_bytes = uint64(v);} 00088 {double v; 00089 if(!a_buffer.read(v)) return false; 00090 m_zip_bytes = uint64(v);} 00091 if(!a_buffer.read(fOffset)) return false; 00092 00093 } else if(v<=6) { 00094 if(!a_buffer.read(fCompress)) return false; 00095 if(!a_buffer.read(fBasketSize)) return false; 00096 if(!a_buffer.read(fEntryOffsetLen)) return false; 00097 if(!a_buffer.read(m_write_basket)) return false; 00098 if(!a_buffer.read(m_entry_number)) return false; 00099 if(!a_buffer.read(fOffset)) return false; 00100 if(!a_buffer.read(fMaxBaskets)) return false; 00101 {double v; 00102 if(!a_buffer.read(v)) return false; 00103 m_entries = uint64(v);} 00104 {double v; 00105 if(!a_buffer.read(v)) return false; 00106 m_tot_bytes = uint64(v);} 00107 {double v; 00108 if(!a_buffer.read(v)) return false; 00109 m_zip_bytes = uint64(v);} 00110 00111 } else if(v<=7) { 00112 if(!a_buffer.read(fCompress)) return false; 00113 if(!a_buffer.read(fBasketSize)) return false; 00114 if(!a_buffer.read(fEntryOffsetLen)) return false; 00115 if(!a_buffer.read(m_write_basket)) return false; 00116 if(!a_buffer.read(m_entry_number)) return false; 00117 if(!a_buffer.read(fOffset)) return false; 00118 if(!a_buffer.read(fMaxBaskets)) return false; 00119 if(!a_buffer.read(fSplitLevel)) return false; 00120 {double v; 00121 if(!a_buffer.read(v)) return false; 00122 m_entries = uint64(v);} 00123 {double v; 00124 if(!a_buffer.read(v)) return false; 00125 m_tot_bytes = uint64(v);} 00126 {double v; 00127 if(!a_buffer.read(v)) return false; 00128 m_zip_bytes = uint64(v);} 00129 00130 } else if(v<=9) { 00131 if(!AttFill_stream(a_buffer)) return false; 00132 if(!a_buffer.read(fCompress)) return false; 00133 if(!a_buffer.read(fBasketSize)) return false; 00134 if(!a_buffer.read(fEntryOffsetLen)) return false; 00135 if(!a_buffer.read(m_write_basket)) return false; 00136 if(!a_buffer.read(m_entry_number)) return false; 00137 if(!a_buffer.read(fOffset)) return false; 00138 if(!a_buffer.read(fMaxBaskets)) return false; 00139 if(!a_buffer.read(fSplitLevel)) return false; 00140 {double v; 00141 if(!a_buffer.read(v)) return false; 00142 m_entries = uint64(v);} 00143 {double v; 00144 if(!a_buffer.read(v)) return false; 00145 m_tot_bytes = uint64(v);} 00146 {double v; 00147 if(!a_buffer.read(v)) return false; 00148 m_zip_bytes = uint64(v);} 00149 00150 } else if(v<=10) { 00151 if(!AttFill_stream(a_buffer)) return false; 00152 00153 if(!a_buffer.read(fCompress)) return false; 00154 if(!a_buffer.read(fBasketSize)) return false; 00155 if(!a_buffer.read(fEntryOffsetLen)) return false; 00156 if(!a_buffer.read(m_write_basket)) return false; 00157 {uint64 v; 00158 if(!a_buffer.read(v)) return false; 00159 m_entry_number = uint32(v);} 00160 if(!a_buffer.read(fOffset)) return false; 00161 if(!a_buffer.read(fMaxBaskets)) return false; 00162 if(!a_buffer.read(fSplitLevel)) return false; 00163 00164 {uint64 v; 00165 if(!a_buffer.read(v)) return false; 00166 m_entries = v;} 00167 {uint64 v; 00168 if(!a_buffer.read(v)) return false; 00169 m_tot_bytes = v;} 00170 {uint64 v; 00171 if(!a_buffer.read(v)) return false; 00172 m_zip_bytes = v;} 00173 00174 } else { //v>=11 00175 00176 if(!AttFill_stream(a_buffer)) return false; 00177 if(!a_buffer.read(fCompress)) return false; 00178 if(!a_buffer.read(fBasketSize)) return false; 00179 if(!a_buffer.read(fEntryOffsetLen)) return false; 00180 if(!a_buffer.read(m_write_basket)) return false; 00181 {uint64 v; 00182 if(!a_buffer.read(v)) return false; 00183 m_entry_number = uint32(v);} 00184 if(!a_buffer.read(fOffset)) return false; 00185 if(!a_buffer.read(fMaxBaskets)) return false; 00186 if(!a_buffer.read(fSplitLevel)) return false; 00187 {uint64 v; 00188 if(!a_buffer.read(v)) return false; 00189 m_entries = v;} 00190 {uint64 v; 00191 if(!a_buffer.read(v)) return false;} //fFirstEntry 00192 {uint64 v; 00193 if(!a_buffer.read(v)) return false; 00194 m_tot_bytes = v;} 00195 {uint64 v; 00196 if(!a_buffer.read(v)) return false; 00197 m_zip_bytes = v;} 00198 } 00199 00200 //::printf("debug : branch::stream : %s : fSplitLevel %d\n",m_name.c_str(),fSplitLevel); 00201 00202 //TObjArray 00203 //::printf("debug : branch::stream : branches : begin\n"); 00204 {ifac::args args; 00205 if(!m_branches.stream(a_buffer,m_fac,args)) { 00206 m_out << "inlib::rroot::branch::stream :" 00207 << " can't read branches." 00208 << std::endl; 00209 return false; 00210 }} 00211 //::printf("debug : branch::stream : branches : end %d\n", 00212 // m_branches.size()); 00213 00214 /* We see that with LHCb files. 00215 if(m_entry_number!=m_entries) { 00216 m_out << "inlib::rroot::branch::stream :" 00217 << " for branch " << sout(m_name) << " :" 00218 << " WARNING : m_entry_number!=m_entries." 00219 << " m_entry_number " << m_entry_number 00220 << " m_entries " << m_entries 00221 << std::endl; 00222 //return false; 00223 } 00224 */ 00225 00226 //TObjArray 00227 //::printf("debug : branch::stream : leaves : begin\n"); 00228 {ifac::args args; 00229 args[ifac::arg_branch()] = this; 00230 if(!m_leaves.stream(a_buffer,m_fac,args)) { 00231 m_out << "inlib::rroot::branch::stream :" 00232 << " can't read leaves." 00233 << std::endl; 00234 return false; 00235 }} 00236 //::printf("debug : branch::stream : leaves : end\n"); 00237 00238 //TObjArray 00239 //IMPORTANT : accept_null=true 00240 //::printf("debug : branch::stream : streamed_baskets : begin\n"); 00241 {ifac::args args; 00242 if(!m_streamed_baskets.stream(a_buffer,m_fac,args,true)) { 00243 m_out << "inlib::rroot::branch::stream :" 00244 << " can't read baskets." 00245 << std::endl; 00246 return false; 00247 }} 00248 //::printf("debug : branch::stream : streamed_baskets : end\n"); 00249 00250 fNleaves = m_leaves.size(); 00251 00252 if(fMaxBaskets<=0) { 00253 m_out << "inlib::rroot::branch::stream :" 00254 << " fMaxBaskets null." 00255 << std::endl; 00256 return false; 00257 } 00258 00259 fBasketEntry = new int[fMaxBaskets]; 00260 fBasketBytes = new int[fMaxBaskets]; 00261 fBasketSeek = new seek[fMaxBaskets]; 00262 {for(uint32 i=0;i<fMaxBaskets;i++) { 00263 fBasketEntry[i] = 0; 00264 fBasketBytes[i] = 0; 00265 fBasketSeek[i] = 0; 00266 }} 00267 00268 if(v<6) { 00269 {uint32 n; 00270 if(!a_buffer.read_array<int>(fMaxBaskets,fBasketEntry,n)) { 00271 _clear(); 00272 return false; 00273 }} 00274 if(v<=4) { 00275 for (uint32 i=0;i<fMaxBaskets;i++) fBasketBytes[i] = 0; 00276 } else { 00277 uint32 n; 00278 if(!a_buffer.read_array<int>(fMaxBaskets,fBasketBytes,n)) { 00279 _clear(); 00280 return false; 00281 } 00282 } 00283 if(v<2) { 00284 //GB : comment. 00285 //for(int i=0;i<m_write_basket;i++) { 00286 // fBasketSeek[i] = getBasket(i)->seekKey(); 00287 //} 00288 m_out << "inlib::rroot::branch::stream :" 00289 << " v < 2. Not (yet) handled." 00290 << std::endl; 00291 _clear(); 00292 return false; 00293 } else { 00294 int n; 00295 if(!a_buffer.read(n)) { 00296 _clear(); 00297 return false; 00298 } 00299 for(int i=0;i<n;i++) { 00300 seek32 s; 00301 if(!a_buffer.read(s)) { 00302 _clear(); 00303 return false; 00304 } 00305 fBasketSeek[i] = s; 00306 } 00307 } 00308 00309 } else if(v<=9) { 00310 // See TStreamerInfo::ReadBuffer::ReadBasicPointer 00311 00312 //Int_t[fMaxBaskets] 00313 {char isArray; 00314 if(!a_buffer.read(isArray)) { 00315 _clear(); 00316 return false; 00317 } 00318 if(isArray) { 00319 if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) { 00320 _clear(); 00321 return false; 00322 } 00323 }} 00324 00325 //Int_t[fMaxBaskets] 00326 {char isArray; 00327 if(!a_buffer.read(isArray)) { 00328 _clear(); 00329 return false; 00330 } 00331 if(isArray) { 00332 if(!a_buffer.read_fast_array<int>(fBasketEntry,fMaxBaskets)) { 00333 _clear(); 00334 return false; 00335 } 00336 }} 00337 00338 //Seek_t[fMaxBaskets] 00339 {char isBigFile; 00340 if(!a_buffer.read(isBigFile)) { 00341 _clear(); 00342 return false; 00343 } 00344 if(isBigFile==2) { 00345 if(!a_buffer.read_fast_array<seek>(fBasketSeek,fMaxBaskets)) { 00346 _clear(); 00347 return false; 00348 } 00349 } else { 00350 for(uint32 i=0;i<fMaxBaskets;i++) { 00351 seek32 s; 00352 if(!a_buffer.read(s)) { 00353 _clear(); 00354 return false; 00355 } 00356 fBasketSeek[i] = s; 00357 } 00358 }} 00359 00360 } else { //v>=10 00361 // See TStreamerInfo::ReadBuffer::ReadBasicPointer 00362 00363 //Int_t[fMaxBaskets] 00364 {char isArray; 00365 if(!a_buffer.read(isArray)) { 00366 _clear(); 00367 return false; 00368 } 00369 if(isArray) { 00370 if(!a_buffer.read_fast_array<int>(fBasketBytes,fMaxBaskets)) { 00371 _clear(); 00372 return false; 00373 } 00374 }} 00375 00376 //Long64_t[fMaxBaskets] 00377 {char isArray; 00378 if(!a_buffer.read(isArray)) { 00379 _clear(); 00380 return false; 00381 } 00382 if(isArray) { 00383 uint64* v = new uint64[fMaxBaskets]; 00384 if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) { 00385 _clear(); 00386 return false; 00387 } 00388 for(uint32 i=0;i<fMaxBaskets;i++) fBasketEntry[i] = int(v[i]); 00389 delete [] v; 00390 }} 00391 00392 //Long64_t[fMaxBaskets] 00393 {char isArray; 00394 if(!a_buffer.read(isArray)) { 00395 _clear(); 00396 return false; 00397 } 00398 if(isArray) { 00399 uint64* v = new uint64[fMaxBaskets]; 00400 if(!a_buffer.read_fast_array<uint64>(v,fMaxBaskets)) { 00401 _clear(); 00402 return false; 00403 } 00404 for(uint32 i=0;i<fMaxBaskets;i++) fBasketSeek[i] = v[i]; 00405 delete [] v; 00406 }} 00407 } 00408 00409 if(v>2) { 00410 //TString 00411 std::string fileName; 00412 if(!a_buffer.read(fileName)) { 00413 _clear(); 00414 return false; 00415 } 00416 } 00417 00418 //FIXME if (v < 4) SetAutoDelete(kTRUE); 00419 //FIXME gROOT->SetReadingObject(kFALSE); 00420 if(!a_buffer.check_byte_count(s, c,"TBranch")) { 00421 _clear(); 00422 return false; 00423 } 00424 00425 //GB : analyse fBasketEntry. 00426 m_first_last.clear(); 00427 {// There are (m_write_basket+1) sensitive elements in fBasketEntry : 00428 // (Do we have to check that ?) 00429 for(uint32 i=0;i<m_write_basket;i++) { 00430 uint32 first = fBasketEntry[i]; 00431 uint32 last = fBasketEntry[i+1]-1; 00432 m_first_last.push_back(std::pair<uint32,uint32>(first,last)); 00433 } 00434 if(m_entry_number) { 00435 uint32 first = fBasketEntry[m_write_basket]; 00436 uint32 last = m_entry_number-1; 00437 m_first_last.push_back(std::pair<uint32,uint32>(first,last)); 00438 }} 00439 //_dump_first_last(); 00440 00441 //GB : analyse fBasketSeek : 00442 {uint32 num = 0; 00443 uint32 mxi = 0; 00444 for(uint32 i=0;i<fMaxBaskets;i++) { 00445 if(!fBasketSeek[i]) continue; 00446 num++; 00447 mxi = inlib::mx(i,mxi); 00448 } 00449 if(m_write_basket) { 00450 if((num!=m_write_basket)||(mxi!=(m_write_basket-1))) { 00451 m_out << "inlib::rroot::branch::stream :" 00452 << " fBasketSeek[] inconsistent with m_write_basket." 00453 << " m_write_basket " << m_write_basket 00454 << " num " << num 00455 << " mxi " << mxi 00456 << std::endl; 00457 _clear(); 00458 return false; 00459 } 00460 }} 00461 00462 //GB : analyse m_streamed_baskets : 00463 {std::vector<basket*>::iterator it; 00464 int index=0; 00465 for(it=m_streamed_baskets.begin(); 00466 it!=m_streamed_baskets.end();++it,index++) { 00467 if(*it) { 00468 if(!(*it)->buf()||!(*it)->buf_size()) { 00469 m_out << "inlib::rroot::branch::stream :" 00470 << " expect a basket with a not empty buffer." 00471 << std::endl; 00472 return false; 00473 } 00474 //in the below, false is to say m_baskets is not owner of *it. 00475 m_baskets[index] = std::pair<basket*,bool>(*it,false); 00476 } 00477 }} 00478 00479 return true; 00480 } 00481 00482 public: 00483 //virtual for branch_element 00484 00485 virtual bool read_leaves(buffer& a_buffer){ 00486 std::vector<base_leaf*>::const_iterator it; 00487 for(it=m_leaves.begin();it!=m_leaves.end();++it) { 00488 if(!(*it)->read_basket(a_buffer)) { 00489 m_out << "inlib::rroot::branch::read_leaves :" 00490 << " read_basket failed." 00491 << std::endl; 00492 return false; 00493 } 00494 } 00495 return true; 00496 } 00497 00498 virtual bool find_entry(uint32 a_entry,uint32& a_nbytes){ 00499 // Read all leaves of entry and return total number of bytes : 00500 // The input argument entry is the entry serial number in the current tree. 00501 a_nbytes = 0; 00502 //if(_test_bit(kDoNotProcess())) return true; 00503 00504 //if(fReadEntry == (int)a_entry) return true; 00505 if(a_entry>=m_entry_number) { 00506 //m_out << "inlib::rroot::branch::find_entry :" 00507 // << " for branch " << sout(m_name) << " :" 00508 // << " a_entry not within [0," << m_entry_number << "[." 00509 // << std::endl; 00510 //return false; 00511 return true; //CERN-ROOT does not consider it is an error. 00512 } 00513 if(!m_entry_number || m_first_last.empty() ) { //GB 00514 m_out << "inlib::rroot::branch::find_entry :" 00515 << " nothing to read." 00516 << std::endl; 00517 return false; //nothing to read. 00518 } 00519 00520 if(m_read_basket>=m_first_last.size()) { 00521 m_out << "inlib::rroot::branch::find_entry :" 00522 << " bad m_first_last access." 00523 << std::endl; 00524 return false; 00525 } 00526 00527 uint32 first = m_first_last[m_read_basket].first; 00528 uint32 last = m_first_last[m_read_basket].second; 00529 00530 // Are we still in the same ReadBasket? 00531 if((a_entry<first)||(a_entry>last)) { 00532 m__read_basket = 0; 00533 uint32 old_read_basket = m_read_basket; 00534 00535 //look first in the next basket window : 00536 bool found = false; 00537 if((m_read_basket+1)<m_first_last.size()) { 00538 first = m_first_last[m_read_basket+1].first; 00539 last = m_first_last[m_read_basket+1].second; 00540 if((a_entry>=first)&&(a_entry<=last)) { 00541 m_read_basket++; 00542 found = true; 00543 } 00544 } 00545 if(!found) { 00546 uint32 count = 0; 00547 std::vector< std::pair<uint32,uint32> >::const_iterator it; 00548 for(it=m_first_last.begin();it!=m_first_last.end();++it,count++) { 00549 first = (*it).first; 00550 last = (*it).second; 00551 if((a_entry>=first)&&(a_entry<=last)) { 00552 m_read_basket = count; 00553 found = true; 00554 break; 00555 } 00556 } 00557 } 00558 if(!found) { //something weird in fBasketEntry. 00559 m_out << "inlib::rroot::branch::find_entry :" 00560 << " fancy fBasketEntry." 00561 << std::endl; 00562 return false; 00563 } else { 00564 // if found, erase m_baskets[old_read_basket] to avoid 00565 // having all data in memory ! 00566 std::map<uint32, std::pair<rroot::basket*,bool> >::iterator it = 00567 m_baskets.find(old_read_basket); 00568 if(it!=m_baskets.end()) { 00569 if((*it).second.second) { 00570 basket* bsk = (*it).second.first; 00571 m_baskets.erase(it); 00572 delete bsk; 00573 //::printf("debug : erase basket %d\n",old_read_basket); 00574 } 00575 } 00576 } 00577 } 00578 00579 if(!m__read_basket) { 00580 00581 rroot::basket* bsk = 0; 00582 std::map<uint32, std::pair<basket*,bool> >::iterator it = 00583 m_baskets.find(m_read_basket); 00584 if(it!=m_baskets.end()) { 00585 bsk = (*it).second.first; 00586 } else { 00587 if(m_read_basket>=m_write_basket) { 00588 m_out << "inlib::rroot::branch::find_entry :" 00589 << " basket lacking !" 00590 << " wanting index " << m_read_basket 00591 << ". fBasketSeek entries " << m_write_basket 00592 << std::endl; 00593 return false; 00594 } 00595 if(!fBasketSeek[m_read_basket]) { 00596 m_out << "inlib::rroot::branch::find_entry :" 00597 << " fBasketSeek is null for index " << m_read_basket 00598 << std::endl; 00599 return false; 00600 } 00601 if(!fBasketBytes[m_read_basket]) { 00602 m_out << "inlib::rroot::branch::find_entry :" 00603 << " fBasketBytes is null for index " << m_read_basket 00604 << std::endl; 00605 return false; 00606 } 00607 00608 bsk = get_basket(fBasketSeek[m_read_basket], 00609 fBasketBytes[m_read_basket]); 00610 if(!bsk) { 00611 m_out << "inlib::rroot::branch::find_entry :" 00612 << " can't read basket " << m_read_basket 00613 << " at file pos " << fBasketSeek[m_read_basket] 00614 << " and size " << fBasketBytes[m_read_basket] 00615 << std::endl; 00616 return false; 00617 } 00618 00619 //m_out << "inlib::rroot::branch::find_entry :" 00620 // << " got basket " << m_read_basket 00621 // << " of size " << fBasketBytes[m_read_basket] 00622 // << std::endl; 00623 00624 m_baskets[m_read_basket] = std::pair<basket*,bool>(bsk,true); 00625 } 00626 00627 m__read_basket = bsk; 00628 } 00629 00630 // Set entry offset in buffer and read data from all leaves 00631 //buf->resetMap(); 00632 00633 uint32 bufbegin; 00634 {int* entry_offset = m__read_basket->entry_offset(); 00635 if(entry_offset) { 00636 uint32 index = a_entry-first; 00637 if(index>=m__read_basket->nev()) { 00638 m_out << "inlib::rroot::branch::find_entry :" 00639 << " can't access entry offset " << index 00640 << ". nev " << m__read_basket->nev() 00641 << std::endl; 00642 return false; 00643 } 00644 bufbegin = entry_offset[index]; 00645 //::printf("debug : xxx++ %u : %u\n",index,bufbegin); 00646 } else { 00647 bufbegin = m__read_basket->key_length() + 00648 (a_entry-first)*m__read_basket->nev_buf_size(); 00649 }} 00650 00651 {int* displacement = m__read_basket->displacement(); 00652 if(displacement) { 00653 m_out << "inlib::rroot::branch::find_entry :" 00654 << " not null displacement. Not yet handled." 00655 << std::endl; 00656 //buf->setDisplacement(displacement[a_entry-first]); 00657 } else { 00658 //buf->setDisplacement(); 00659 }} 00660 00661 /* 00662 if(bufbegin>=m__read_basket->buf_size()) { 00663 m_out << "inlib::rroot::branch::find_entry :" 00664 << " bad buffer access for entry " << a_entry 00665 << ". bufbegin " << bufbegin 00666 << ", buf_size " << basket->buf_size() 00667 << ", (entry-first) " << (a_entry-first) 00668 << std::endl; 00669 {int* entry_offset = m__read_basket->entry_offset(); 00670 if(entry_offset) { 00671 uint32 nev = m__read_basket->nev(); 00672 ::printf("debug : eoff : num %d\n",nev); 00673 for(uint32 i=0;i<nev;i++){ 00674 ::printf("debug : eoff %d : %d\n",i,entry_offset[i]); 00675 } 00676 }} 00677 return false; 00678 } 00679 */ 00680 00681 rroot::buffer buffer(m_out,m_file.byte_swap(), 00682 m__read_basket->buf_size(),m__read_basket->buf(),0,false); 00683 buffer.set_offset(bufbegin); 00684 00685 if(!read_leaves(buffer)) { 00686 m_out << "inlib::rroot::branch::find_entry :" 00687 << " can't read leaves for entry " << a_entry 00688 << ". read_basket was " << m_read_basket 00689 << ", first " << first 00690 << ", last " << last 00691 << "." 00692 << std::endl; 00693 return false; 00694 } 00695 00696 //fReadEntry = a_entry; 00697 00698 a_nbytes = buffer.length() - bufbegin; 00699 00700 return true; 00701 } 00702 00703 public: 00704 branch(ifile& a_file,ifac& a_fac) 00705 :m_file(a_file) 00706 ,m_out(a_file.out()) 00707 ,m_fac(a_fac) 00708 00709 ,m_streamed_baskets(true) 00710 ,m__read_basket(0) 00711 00712 //,m_bits(0) 00713 ,m_name("") 00714 ,m_title("") 00715 ,fAutoDelete(false) 00716 00717 ,m_branches(true) 00718 ,m_leaves(true) 00719 00720 ,fEntryOffsetLen(0) 00721 ,m_write_basket(0) 00722 ,m_entry_number(0) 00723 ,m_read_basket(0) 00724 ,fBasketBytes(0) 00725 ,fBasketEntry(0) 00726 ,fBasketSeek(0) 00727 { 00728 #ifdef INLIB_MEM 00729 mem::increment(s_class().c_str()); 00730 #endif 00731 } 00732 virtual ~branch(){ 00733 _clear(); 00734 #ifdef INLIB_MEM 00735 mem::decrement(s_class().c_str()); 00736 #endif 00737 } 00738 protected: 00739 branch(const branch& a_from) 00740 : iro(a_from) 00741 ,m_file(a_from.m_file),m_out(a_from.m_out),m_fac(a_from.m_fac) 00742 ,m_streamed_baskets(false),m__read_basket(0) 00743 ,m_branches(false),m_leaves(false){} 00744 branch& operator=(const branch&){return *this;} 00745 public: 00746 uint32 entry_number() const {return m_entry_number;} 00747 const std::string& name() const {return m_name;} 00748 const std::string& title() const {return m_title;} 00749 const std::vector<base_leaf*>& leaves() const {return m_leaves;} 00750 const std::vector<branch*>& branches() const {return m_branches;} 00751 00752 bool show(std::ostream& a_out,uint32 a_entry){ 00753 // Print values of all active leaves for entry : 00754 // if entry==-1, print current entry (default) 00755 uint32 n; 00756 if(!find_entry(a_entry,n)) return false; 00757 00758 std::vector<base_leaf*>::const_iterator it; 00759 for(it=m_leaves.begin();it!=m_leaves.end();++it) { 00760 base_leaf* bl = *it; 00761 00762 uint32 num = bl->num_elem(); 00763 num = inlib::mn<uint32>(num,10); 00764 if(!num) continue; 00765 00766 {std::string s; 00767 uint32 len = bl->name().size()+128; 00768 inlib::sprintf(s,len," %-15s = ",bl->name().c_str()); 00769 a_out << s;} 00770 00771 for(uint32 i=0;i<num;i++) { 00772 if(i) a_out << ", "; 00773 bl->print_value(a_out,i); 00774 } 00775 00776 a_out << std::endl; 00777 } 00778 00779 return true; 00780 } 00781 protected: 00782 basket* get_basket(seek a_pos,uint32 a_len) { 00783 //if(fBranch.tree().memoryFull(fBufferSize)) fBranch.dropBaskets(); 00784 if(!a_len) return 0; 00785 00786 rroot::basket* basket = 00787 new rroot::basket(m_file,a_pos,a_len); //basket is a key. 00788 if(!basket->read_file()) { 00789 m_out << "inlib::rroot::branch::get_basket :" 00790 << " read_file() failed." 00791 << std::endl; 00792 delete basket; 00793 return 0; 00794 } 00795 {rroot::buffer buffer(m_out,m_file.byte_swap(), 00796 a_len,basket->buf(),0,false); 00797 if(!basket->stream(buffer)) { 00798 m_out << "inlib::rroot::branch::get_basket :" 00799 << " basket stream failed." 00800 << std::endl; 00801 delete basket; 00802 return 0; 00803 }} 00804 unsigned int sz; 00805 char* buf = basket->get_object_buffer(sz); //basket owns buf. 00806 if(!buf) { 00807 m_out << "inlib::rroot::branch::get_basket :" 00808 << " get_object_buffer() failed." 00809 << std::endl; 00810 delete basket; 00811 return 0; 00812 } 00813 00814 if(basket->seek_key()!=a_pos) { //consistency check. 00815 m_out << "inlib::rroot::branch::get_basket :" 00816 << " seek anomaly." 00817 << " a_pos " << a_pos 00818 << " seek_key() " << basket->seek_key() 00819 << std::endl; 00820 delete basket; 00821 return 0; 00822 } 00823 //if(basket->nbytes()!=a_len) { //consistency check. 00824 // m_out << "inlib::rroot::branch::get_basket :" 00825 // << " WARNING : length anomaly." 00826 // << " a_len " << a_len 00827 // << " nbytes() " << basket->nbytes() 00828 // << std::endl; 00829 //} 00830 00831 if(fEntryOffsetLen) { 00832 if(!basket->read_offset_tables()) { 00833 m_out << "inlib::rroot::branch::get_basket :" 00834 << " read_offset_tables failed." 00835 << std::endl; 00836 delete basket; 00837 return 0; 00838 }} 00839 00840 return basket; 00841 } 00842 protected: 00843 void _clear() { 00844 delete [] fBasketEntry; 00845 delete [] fBasketBytes; 00846 delete [] fBasketSeek; 00847 fBasketEntry = 0; 00848 fBasketBytes = 0; 00849 fBasketSeek = 0; 00850 00851 {std::map<uint32, std::pair<basket*,bool> >::iterator it; 00852 for(it=m_baskets.begin();it!=m_baskets.end();++it) { 00853 if((*it).second.second) delete (*it).second.first; 00854 } 00855 m_baskets.clear();} 00856 00857 m_branches.cleanup(); 00858 m_leaves.cleanup(); 00859 m_streamed_baskets.cleanup(); 00860 } 00861 00862 void _dump_first_last() { 00863 m_out << "inlib::rroot::branch::_dump_first_last :" 00864 << " first_last " << m_first_last.size() 00865 << std::endl; 00866 std::vector< std::pair<uint32,uint32> >::const_iterator it; 00867 for(it=m_first_last.begin();it!=m_first_last.end();++it) { 00868 uint32 first = (*it).first; 00869 uint32 last = (*it).second; 00870 m_out << "inlib::rroot::branch::stream :" 00871 << " first " << first 00872 << " last " << last 00873 << std::endl; 00874 } 00875 } 00876 00877 //bool _test_bit(uint32 a_f) const { 00878 // return (bool)(m_bits & a_f); 00879 //} 00880 static std::string sout(const std::string& a_string) { 00881 return std::string("\"")+a_string+"\""; 00882 } 00883 00884 00885 protected: 00886 //Tree& fTree; 00887 ifile& m_file; 00888 std::ostream& m_out; 00889 ifac& m_fac; 00890 std::vector< std::pair<uint32,uint32> > m_first_last; 00891 std::map<uint32, std::pair<basket*,bool> > m_baskets; 00892 ObjArray<basket> m_streamed_baskets; 00893 basket* m__read_basket; //optimization 00894 protected: 00895 //Object 00896 //uint32 m_bits; 00897 //Named 00898 std::string m_name; 00899 std::string m_title; 00900 00901 bool fAutoDelete; 00902 ObjArray<branch> m_branches; 00903 ObjArray<base_leaf> m_leaves; 00904 uint32 fEntryOffsetLen; // Initial Length of fEntryOffset table in the basket buffers 00905 uint32 m_write_basket; // Last basket number written 00906 uint32 m_entry_number; // Current entry number (last one filled in this branch) 00907 uint32 m_read_basket; 00908 int* fBasketBytes; //[fMaxBaskets] Lenght of baskets on file 00909 int* fBasketEntry; //[fMaxBaskets] Table of first entry in eack basket 00910 seek* fBasketSeek; //[fMaxBaskets] Addresses of baskets on file 00911 }; 00912 00913 }} 00914 00915 #endif