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