inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/rroot/branch
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines