Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/wroot/basket 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_wroot_basket
0005 #define tools_wroot_basket
0006 
0007 #include "ibo"
0008 #include "key"
0009 #include "buffer"
0010 #include "../cmemT"
0011 
0012 namespace tools {
0013 namespace wroot {
0014 
0015 class basket : public virtual ibo, public key {
0016   typedef key parent;
0017 public:
0018   static const std::string& s_class() {
0019     static const std::string s_v("tools::wroot::basket");
0020     return s_v;
0021   }
0022 public: //ibo
0023   virtual const std::string& store_cls() const {
0024     static const std::string s_v("TBasket");
0025     return s_v;
0026   }
0027   virtual bool stream(buffer& a_buffer) const {
0028     // in principle we pass here only for the last basket
0029     // of a branch when it is streamed from branch::stream().
0030 
0031     // We pass also here in the case of filling "tree in a tree" (MEMPHYS sim).
0032 
0033     // some consitency checks :
0034     //G.Barrand : the below test is "too much". Someone
0035     //            may have to write a tree (and then a basket)
0036     //            which had been never filled.
0037     //            Moreover with the today branch code, a
0038     //              basket.write_on_file()
0039     //            happens only in a branch.fill() that deletes
0040     //            the basket just after the call.
0041     if(m_seek_key) {
0042       m_out << "tools::wroot::basket::stream :"
0043             << " m_seek_key is not null (" << m_seek_key << ")."
0044             << std::endl;
0045       return false;
0046     }
0047     if(m_last) {
0048       m_out << "tools::wroot::basket::stream :"
0049             << " m_last is not null."
0050             << std::endl;
0051       return false;
0052     }
0053     if(!m_entry_offset) {
0054       m_out << "tools::wroot::basket::stream :"
0055             << " m_entry_offset is null."
0056             << std::endl;
0057       return false;
0058     }
0059 
0060    {uint32 _last = m_data.length()+m_key_length;
0061     if(_last>m_last) {
0062       const_cast<basket&>(*this).m_last = _last;
0063     }}
0064     if(m_last>m_buf_size) {
0065       const_cast<basket&>(*this).m_buf_size = m_last;
0066     }
0067 
0068     char flag = 11;
0069     if(m_displacement)  flag += 40;
0070     if(!_stream_header(a_buffer,m_verbose,flag)) return false;
0071 
0072     if(m_entry_offset && m_nev) {
0073       if(!a_buffer.write_array(m_entry_offset,m_nev)) return false;
0074       if(m_displacement) {
0075         if(!a_buffer.write_array(m_displacement,m_nev)) return false;
0076       }
0077     }
0078 
0079     if(m_data.to_displace()) {
0080       if(!const_cast<basket&>(*this).m_data.displace_mapped(m_key_length)) {
0081         m_out << "tools::wroot::basket::stream :"
0082               << " m_data.displace_mapped() failed."
0083               << std::endl;
0084         return false;
0085       }
0086     }
0087 
0088     buffer bref(m_out,a_buffer.byte_swap(),256);
0089     if(!_stream_header(bref,m_verbose)) return false; //then header stored twice !
0090     if(!bref.write_fast_array(m_data.buf(),m_data.length())) return false;
0091     if(!a_buffer.write_fast_array(bref.buf(),bref.length())) return false;
0092 
0093     return true;
0094   }
0095 public:
0096   basket(std::ostream& a_out,
0097          bool a_byte_swap,
0098          seek a_seek_directory,
0099          const std::string& a_object_name,
0100          const std::string& a_object_title,
0101          const std::string& a_object_class,
0102          uint32 a_basket_size,bool a_verbose)
0103   :parent(a_out,a_seek_directory,a_object_name,a_object_title,a_object_class)
0104   ,m_verbose(a_verbose)
0105   ,m_data(a_out,a_byte_swap,a_basket_size)
0106   ,m_nev_buf_size(1000)
0107   ,m_nev(0)
0108   ,m_last(0)
0109   ,m_entry_offset(0)
0110   ,m_displacement(0)
0111   {
0112     if(m_version>big_file_version_tag()) {
0113     } else {
0114       // G.Barrand : April 2016 : WARNING : this is a change in the ROOT/IO format compared to CERN-ROOT/4.x :
0115       // We follow the logic found on CERN-ROOT/5.x that enforces "+1000" on all baskets.
0116       m_version += big_file_version_tag();
0117     }
0118 
0119     m_key_length = header_record_size(m_version);
0120     initialize_zero();
0121 
0122     if(m_nev_buf_size) {
0123       m_entry_offset = new int[m_nev_buf_size];
0124      {for(uint32 i=0;i<m_nev_buf_size;i++) m_entry_offset[i] = 0;}
0125     }
0126   }
0127   virtual ~basket(){
0128     delete [] m_entry_offset;
0129     delete [] m_displacement;
0130     m_entry_offset = 0;
0131     m_displacement = 0;
0132   }
0133 protected:
0134   basket(const basket& a_from)
0135   :ibo(a_from)
0136   ,parent(a_from)
0137   ,m_verbose(a_from.m_verbose)
0138   ,m_data(m_out,a_from.m_data.byte_swap(),256)
0139   ,m_nev_buf_size(a_from.m_nev_buf_size)
0140   ,m_nev(a_from.m_nev)
0141   ,m_last(a_from.m_last)
0142   ,m_entry_offset(0)
0143   ,m_displacement(0)
0144   {
0145   }
0146   basket& operator=(const basket& a_from){
0147     parent::operator=(a_from);
0148     m_nev_buf_size = a_from.m_nev_buf_size;
0149     m_nev = a_from.m_nev;
0150     m_last = a_from.m_last;
0151     return *this;
0152   }
0153 public:
0154   const buffer& datbuf() const {return m_data;}
0155   buffer& datbuf() {return m_data;}
0156 
0157   const int* entry_offset() const {return m_entry_offset;}
0158   int* entry_offset() {return m_entry_offset;}
0159 
0160   const int* displacement() const {return m_displacement;}
0161   int* displacement() {return m_displacement;}
0162 
0163   uint32 nev_buf_size() const {return m_nev_buf_size;}
0164   uint32 nev() const {return m_nev;}
0165   uint32 last() const {return m_last;}
0166 
0167   void set_nev(uint32 a_last,uint32 a_nev_buf_size,uint32 a_nev,const int* a_entry_offset,const int* a_displacement) {
0168     //used in mpi_create_basket.
0169     m_last = a_last;
0170     m_nev_buf_size = a_nev_buf_size;
0171     m_nev = a_nev;
0172     delete [] m_entry_offset;
0173     m_entry_offset = 0;
0174     delete [] m_displacement;
0175     m_displacement = 0;
0176 
0177     if(a_entry_offset && m_nev_buf_size) {
0178       m_entry_offset = new int[m_nev_buf_size];
0179       for(uint32 i=0;i<m_nev;i++) m_entry_offset[i] = a_entry_offset[i];
0180     }
0181 
0182     if(a_displacement && m_nev_buf_size) {
0183       m_displacement = new int[m_nev_buf_size];
0184       for(uint32 i=0;i<m_nev;i++) m_displacement[i] = a_displacement[i];
0185     }
0186   }
0187 
0188   bool update(uint32 a_offset) {
0189     if(m_entry_offset) {
0190       if((m_nev+1)>=m_nev_buf_size) { // for the +1, we follow CERN-ROOT/TBasket logic that wants to store
0191                                       // nev+1 elements for m_entry_offset in the write_on_file() method.
0192         uint32 newsize = max_of<uint32>(10,2*m_nev_buf_size);
0193         if(!cmem_realloc<int>(m_entry_offset,newsize,m_nev_buf_size,true)){
0194           m_out << "tools::wroot::basket::update : realloc failed." << std::endl;
0195           return false;
0196         }
0197         if(m_displacement) {
0198           if(!cmem_realloc<int>(m_displacement,newsize,m_nev_buf_size,true)){
0199             m_out << "tools::wroot::basket::update : realloc failed." << std::endl;
0200             return false;
0201           }
0202         }
0203         m_nev_buf_size = newsize;
0204       }
0205       m_entry_offset[m_nev] = (int)a_offset;
0206     }
0207     m_nev++;
0208     return true;
0209   }
0210 
0211   bool write_on_file(ifile& a_file,uint16 a_cycle,uint32& a_nbytes) {
0212     // write m_data buffer into file.
0213     //NOTE : m_data does not contain the key at its head.
0214     //       At this point m_seek_key should be 0.
0215 
0216     a_nbytes = 0;
0217 
0218     if(m_seek_key) {
0219       m_out << "tools::wroot::basket::write_on_file :"
0220             << " m_seek_key should be 0 (" << m_seek_key << ")."
0221             << std::endl;
0222       return false;
0223     }
0224 
0225     if(m_version>big_file_version_tag()) {
0226     } else {
0227       m_out << "tools::wroot::basket::write_on_file : "
0228             << " we should not pass here (1)."
0229             << std::endl;
0230       return false;
0231     }
0232 
0233     // Transfer m_entry_offset table at the end of fBuffer. Offsets to fBuffer
0234     // are transformed in entry length to optimize compression algorithm.
0235     m_last = m_key_length+m_data.length();
0236     if(m_entry_offset) {
0237       if(!m_data.write_array<int>(m_entry_offset,m_nev+1)) { // for the +1 we follow CERN-ROOT/TBasket logic.
0238         delete [] m_entry_offset;
0239         m_entry_offset = 0;
0240         return false;
0241       }
0242       delete [] m_entry_offset;
0243       m_entry_offset = 0;
0244       if(m_displacement) {
0245         if(!m_data.write_array<int>(m_displacement,m_nev+1)) {
0246           delete [] m_displacement;
0247           m_displacement = 0;
0248           return false;
0249         }
0250         delete [] m_displacement;
0251         m_displacement = 0;
0252       }
0253     }
0254 
0255     m_object_size = m_data.length(); //uncompressed size.
0256 
0257     m_cycle = a_cycle;
0258 
0259     if(!m_data.displace_mapped(m_key_length)) return false;
0260 
0261     char* kbuf = 0;
0262     uint32 klen = 0;
0263     bool kdelete = false;
0264     a_file.compress_buffer(m_data,kbuf,klen,kdelete);
0265 
0266     if(!initialize(a_file,klen)) { //it will do a m_seek_key = a_file.END() and then a_file.set_END(...)
0267       m_out << "tools::wroot::basket::write_on_file :"
0268             << " initialize() failed."
0269             << std::endl;
0270       if(kdelete) delete [] kbuf;
0271       return false;
0272     }
0273 
0274     //write header of the key :
0275    {buffer bref(m_out,a_file.byte_swap(),256);
0276     if(!_stream_header(bref,a_file.verbose())) return false;
0277     if(bref.length()!=m_key_length) {
0278       m_out << "tools::wroot::basket::write_on_file :"
0279             << " key len anomaly " << bref.length()
0280             << " m_key_length " << m_key_length
0281             << std::endl;
0282       if(kdelete) delete [] kbuf;
0283       return false;
0284     }
0285     ::memcpy(m_buffer,bref.buf(),m_key_length);}
0286 
0287     ::memcpy(m_buffer+m_key_length,kbuf,klen);
0288     if(kdelete) delete [] kbuf;
0289 
0290     uint32 nbytes;
0291     if(!parent::write_file(a_file,nbytes)) return false;
0292 
0293     m_data.pos() = m_data.buf(); //empty m_data.
0294 
0295     a_nbytes = m_key_length + klen;
0296     return true;
0297   }
0298 protected:
0299   uint32 header_record_size(uint32 a_version) const {
0300     // header only.
0301     uint32 nbytes = parent::record_size(a_version);
0302 
0303     nbytes += sizeof(short);   //version
0304     nbytes += sizeof(uint32); //m_buf_size
0305     nbytes += sizeof(uint32); //m_nev_buf_size
0306     nbytes += sizeof(uint32); //m_nev
0307     nbytes += sizeof(uint32); //m_last
0308     nbytes += sizeof(char);   //flag
0309 
0310     return nbytes;
0311   }
0312   bool _stream_header(buffer& a_buffer,bool a_verbose,char a_flag = 0) const {
0313    {uint32 l = parent::record_size(m_version);
0314     if((a_buffer.length()+l)>a_buffer.size()) {
0315       if(!a_buffer.expand(a_buffer.size()+l)) return false;
0316     }
0317     wbuf wb(m_out,a_buffer.byte_swap(),a_buffer.max_pos(),a_buffer.pos());
0318     if(!parent::to_buffer(wb,a_verbose)) return false;}
0319 
0320     if(!a_buffer.write_version(2)) return false;
0321     if(!a_buffer.write(m_buf_size)) return false;
0322     if(!a_buffer.write(m_nev_buf_size)) return false;
0323     if(!a_buffer.write(m_nev)) return false;
0324     if(!a_buffer.write(m_last)) return false;
0325     if(!a_buffer.write(a_flag)) return false;
0326     return true;
0327   }
0328 protected:
0329   bool m_verbose;
0330   buffer m_data;
0331 protected:
0332   uint32 m_nev_buf_size;  //Length in Int_t of m_entry_offset
0333   uint32 m_nev;           //Number of entries in basket
0334   uint32 m_last;          //Pointer to last used byte in basket
0335   int* m_entry_offset;    //[m_nev] Offset of entries in fBuffer(TKey)
0336   int* m_displacement;    //![m_nev] Displacement of entries in fBuffer(TKey)
0337 };
0338 
0339 }}
0340 
0341 #endif