Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 2 // See the file tools.license for terms. 3 4 #ifndef tools_wroot_basket 5 #define tools_wroot_basket 6 7 #include "ibo" 8 #include "key" 9 #include "buffer" 10 11 namespace tools { 12 namespace wroot { 13 14 class basket : public virtual ibo, public key 15 typedef key parent; 16 public: 17 static const std::string& s_class() { 18 static const std::string s_v("tools::wroot 19 return s_v; 20 } 21 public: //ibo 22 virtual const std::string& store_cls() const 23 static const std::string s_v("TBasket"); 24 return s_v; 25 } 26 virtual bool stream(buffer& a_buffer) const 27 // in principle we pass here only for the 28 // of a branch when it is streamed from br 29 30 // We pass also here in the case of fillin 31 32 // some consitency checks : 33 //G.Barrand : the below test is "too much" 34 // may have to write a tree (an 35 // which had been never filled. 36 // Moreover with the today bran 37 // basket.write_on_file() 38 // happens only in a branch.fil 39 // the basket just after the ca 40 //if(!m_data.length()) { 41 // // to be sure to not work on a basket al 42 // // with write_on_file() 43 // m_out << "tools::wroot::basket::stream : 44 // << " m_data.length() is null." 45 // << std::endl; 46 // return false; 47 //} 48 if(m_seek_key) { 49 m_out << "tools::wroot::basket::stream : 50 << " m_seek_key is not null (" << 51 << std::endl; 52 return false; 53 } 54 if(m_last) { 55 m_out << "tools::wroot::basket::stream : 56 << " m_last is not null." 57 << std::endl; 58 return false; 59 } 60 if(!m_entry_offset) { 61 m_out << "tools::wroot::basket::stream : 62 << " m_entry_offset is null." 63 << std::endl; 64 return false; 65 } 66 67 {uint32 _last = m_data.length()+m_key_lengt 68 if(_last>m_last) { 69 const_cast<basket&>(*this).m_last = _las 70 }} 71 if(m_last>m_buf_size) { 72 const_cast<basket&>(*this).m_buf_size = 73 } 74 75 char flag = 11; 76 if(m_displacement) flag += 40; 77 if(!_stream_header(a_buffer,m_verbose,flag 78 79 if(m_entry_offset && m_nev) { 80 if(!a_buffer.write_array(m_entry_offset, 81 if(m_displacement) { 82 if(!a_buffer.write_array(m_displacemen 83 } 84 } 85 86 if(m_data.to_displace()) { 87 if(!const_cast<basket&>(*this).m_data.di 88 m_out << "tools::wroot::basket::stream 89 << " m_data.displace_mapped() fa 90 << std::endl; 91 return false; 92 } 93 } 94 95 buffer bref(m_out,a_buffer.byte_swap(),256 96 if(!_stream_header(bref,m_verbose)) return 97 //if(bref.length()!=m_key_length) {} 98 if(!bref.write_fast_array(m_data.buf(),m_d 99 if(!a_buffer.write_fast_array(bref.buf(),b 100 101 return true; 102 } 103 public: 104 basket(std::ostream& a_out, 105 bool a_byte_swap, 106 seek a_seek_directory, 107 const std::string& a_object_name, 108 const std::string& a_object_title, 109 const std::string& a_object_class, 110 uint32 a_basket_size,bool a_verbose) 111 :parent(a_out,a_seek_directory,a_object_name 112 ,m_verbose(a_verbose) 113 ,m_data(a_out,a_byte_swap,a_basket_size) 114 ,m_nev_buf_size(1000) 115 ,m_nev(0) 116 ,m_last(0) 117 ,m_entry_offset(0) 118 ,m_displacement(0) 119 { 120 #ifdef TOOLS_MEM 121 mem::increment(s_class().c_str()); 122 #endif 123 124 if(m_version>big_file_version_tag()) { 125 } else { 126 // G.Barrand : April 2016 : WARNING : th 127 // We follow the logic found on CERN-ROO 128 m_version += big_file_version_tag(); 129 } 130 131 m_key_length = header_record_size(m_versio 132 initialize_zero(); 133 134 if(m_nev_buf_size) { 135 m_entry_offset = new int[m_nev_buf_size] 136 {for(uint32 i=0;i<m_nev_buf_size;i++) m_e 137 } 138 } 139 virtual ~basket(){ 140 delete [] m_entry_offset; 141 delete [] m_displacement; 142 m_entry_offset = 0; 143 m_displacement = 0; 144 #ifdef TOOLS_MEM 145 mem::decrement(s_class().c_str()); 146 #endif 147 } 148 protected: 149 basket(const basket& a_from) 150 :ibo(a_from) 151 ,parent(a_from) 152 ,m_verbose(a_from.m_verbose) 153 ,m_data(m_out,a_from.m_data.byte_swap(),256) 154 ,m_nev_buf_size(a_from.m_nev_buf_size) 155 ,m_nev(a_from.m_nev) 156 ,m_last(a_from.m_last) 157 ,m_entry_offset(0) 158 ,m_displacement(0) 159 { 160 #ifdef TOOLS_MEM 161 mem::increment(s_class().c_str()); 162 #endif 163 } 164 basket& operator=(const basket& a_from){ 165 parent::operator=(a_from); 166 m_nev_buf_size = a_from.m_nev_buf_size; 167 m_nev = a_from.m_nev; 168 m_last = a_from.m_last; 169 return *this; 170 } 171 public: 172 const buffer& datbuf() const {return m_data; 173 buffer& datbuf() {return m_data;} 174 175 const int* entry_offset() const {return m_en 176 int* entry_offset() {return m_entry_offset;} 177 178 const int* displacement() const {return m_di 179 int* displacement() {return m_displacement;} 180 181 uint32 nev_buf_size() const {return m_nev_bu 182 uint32 nev() const {return m_nev;} 183 uint32 last() const {return m_last;} 184 185 void set_nev(uint32 a_last,uint32 a_nev_buf_ 186 //used in mpi_create_basket. 187 m_last = a_last; 188 m_nev_buf_size = a_nev_buf_size; 189 m_nev = a_nev; 190 delete [] m_entry_offset; 191 m_entry_offset = 0; 192 delete [] m_displacement; 193 m_displacement = 0; 194 195 if(a_entry_offset && m_nev_buf_size) { 196 m_entry_offset = new int[m_nev_buf_size] 197 for(uint32 i=0;i<m_nev;i++) m_entry_offs 198 } 199 200 if(a_displacement && m_nev_buf_size) { 201 m_displacement = new int[m_nev_buf_size] 202 for(uint32 i=0;i<m_nev;i++) m_displaceme 203 } 204 } 205 206 bool update(uint32 a_offset) { 207 if(m_entry_offset) { 208 if((m_nev+1)>=m_nev_buf_size) { // for t 209 // nev+1 210 uint32 newsize = mx<uint32>(10,2*m_nev 211 if(!realloc<int>(m_entry_offset,newsiz 212 m_out << "tools::wroot::basket::upda 213 return false; 214 } 215 if(m_displacement) { 216 if(!realloc<int>(m_displacement,news 217 m_out << "tools::wroot::basket::up 218 return false; 219 } 220 } 221 m_nev_buf_size = newsize; 222 } 223 m_entry_offset[m_nev] = (int)a_offset; 224 } 225 m_nev++; 226 return true; 227 } 228 229 bool write_on_file(ifile& a_file,uint16 a_cy 230 // write m_data buffer into file. 231 //NOTE : m_data does not contain the key a 232 // At this point m_seek_key should b 233 234 a_nbytes = 0; 235 236 if(m_seek_key) { 237 m_out << "tools::wroot::basket::write_on 238 << " m_seek_key should be 0 (" << 239 << std::endl; 240 return false; 241 } 242 243 if(m_version>big_file_version_tag()) { 244 } else { 245 m_out << "tools::wroot::basket::write_on 246 << " we should not pass here (1)." 247 << std::endl; 248 return false; 249 /* 250 if(a_file.END()>START_BIG_FILE()) { 251 //GB : enforce m_version>big_file_vers 252 // seek_key>START_BIG_FILE. If not 253 // write a big m_seek_key on a see 254 // a problem when reading. 255 256 //m_out << "tools::wroot::basket::writ 257 // << " WARNING : pos>START_BIG_F 258 // << std::endl; 259 260 m_version += big_file_version_tag(); 261 m_key_length += 8; 262 263 if(m_entry_offset) { 264 for(uint32 i=0;i<m_nev;i++) m_entry_ 265 if(m_displacement) { 266 //??? Do we have to shift them ? 267 m_out << "tools::wroot::basket::wr 268 << " displace logic : m_disp 269 << std::endl; 270 } 271 } 272 273 } 274 */ 275 } 276 277 // Transfer m_entry_offset table at the en 278 // are transformed in entry length to opti 279 m_last = m_key_length+m_data.length(); 280 if(m_entry_offset) { 281 if(!m_data.write_array<int>(m_entry_offs 282 delete [] m_entry_offset; 283 m_entry_offset = 0; 284 return false; 285 } 286 delete [] m_entry_offset; 287 m_entry_offset = 0; 288 if(m_displacement) { 289 if(!m_data.write_array<int>(m_displace 290 delete [] m_displacement; 291 m_displacement = 0; 292 return false; 293 } 294 delete [] m_displacement; 295 m_displacement = 0; 296 } 297 } 298 299 m_object_size = m_data.length(); //uncompr 300 301 m_cycle = a_cycle; 302 303 if(!m_data.displace_mapped(m_key_length)) 304 305 char* kbuf = 0; 306 uint32 klen = 0; 307 bool kdelete = false; 308 a_file.compress_buffer(m_data,kbuf,klen,kd 309 310 if(!initialize(a_file,klen)) { //it will d 311 m_out << "tools::wroot::basket::write_on 312 << " initialize() failed." 313 << std::endl; 314 if(kdelete) delete [] kbuf; 315 return false; 316 } 317 318 //write header of the key : 319 {buffer bref(m_out,a_file.byte_swap(),256); 320 if(!_stream_header(bref,a_file.verbose())) 321 if(bref.length()!=m_key_length) { 322 m_out << "tools::wroot::basket::write_on 323 << " key len anomaly " << bref.len 324 << " m_key_length " << m_key_lengt 325 << std::endl; 326 if(kdelete) delete [] kbuf; 327 return false; 328 } 329 ::memcpy(m_buffer,bref.buf(),m_key_length) 330 331 ::memcpy(m_buffer+m_key_length,kbuf,klen); 332 if(kdelete) delete [] kbuf; 333 334 uint32 nbytes; 335 if(!parent::write_file(a_file,nbytes)) ret 336 337 m_data.pos() = m_data.buf(); //empty m_dat 338 339 a_nbytes = m_key_length + klen; 340 return true; 341 } 342 protected: 343 uint32 header_record_size(uint32 a_version) 344 // header only. 345 uint32 nbytes = parent::record_size(a_vers 346 347 nbytes += sizeof(short); //version 348 nbytes += sizeof(uint32); //m_buf_size 349 nbytes += sizeof(uint32); //m_nev_buf_size 350 nbytes += sizeof(uint32); //m_nev 351 nbytes += sizeof(uint32); //m_last 352 nbytes += sizeof(char); //flag 353 354 return nbytes; 355 } 356 bool _stream_header(buffer& a_buffer,bool a_ 357 {uint32 l = parent::record_size(m_version); 358 if((a_buffer.length()+l)>a_buffer.size()) 359 if(!a_buffer.expand(a_buffer.size()+l)) 360 } 361 wbuf wb(m_out,a_buffer.byte_swap(),a_buffe 362 if(!parent::to_buffer(wb,a_verbose)) retur 363 364 if(!a_buffer.write_version(2)) return fals 365 if(!a_buffer.write(m_buf_size)) return fal 366 if(!a_buffer.write(m_nev_buf_size)) return 367 if(!a_buffer.write(m_nev)) return false; 368 if(!a_buffer.write(m_last)) return false; 369 if(!a_buffer.write(a_flag)) return false; 370 return true; 371 } 372 protected: 373 bool m_verbose; 374 buffer m_data; 375 protected: 376 uint32 m_nev_buf_size; //Length in Int_t of 377 uint32 m_nev; //Number of entries 378 uint32 m_last; //Pointer to last us 379 int* m_entry_offset; //[m_nev] Offset of 380 int* m_displacement; //![m_nev] Displacem 381 }; 382 383 }} 384 385 #endif