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