Warning, /include/Geant4/tools/wroot/mt_ntuple_column_wise 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_mt_ntuple_column_wise
0005 #define tools_wroot_mt_ntuple_column_wise
0006
0007 // mt = multi-threads.
0008
0009 #include "base_pntuple_column_wise"
0010 #include "mt_basket_add"
0011 #include "imt_ntuple"
0012
0013 namespace tools {
0014 namespace wroot {
0015
0016 class mt_ntuple_column_wise : public base_pntuple_column_wise, public virtual imt_ntuple {
0017 typedef base_pntuple_column_wise parent;
0018 protected:
0019 class basket_add : public mt_basket_add {
0020 typedef mt_basket_add parent;
0021 public:
0022 virtual bool add_basket(basket* a_basket) { // we get ownership of a_basket.
0023 if(m_row_mode) {
0024 //m_ntuple.m_out << "debug : add_basket in parallel branch name " << m_parallel_branch.name()
0025 // << ", num existing baskets " << m_parallel_branch.m_parallel_baskets.size() << "." << std::endl;
0026 m_parallel_branch.m_parallel_baskets.push_back(a_basket);
0027 if(ready_to_flush_baskets(m_cols)) {return flush_baskets(m_mutex,m_main_file,m_cols,m_main_branches);}
0028 return true;
0029 } else {
0030 m_mutex.lock();
0031 uint32 add_bytes,nout;
0032 bool status = false;
0033 if(m_main_branch.add_basket(m_main_file,*a_basket,add_bytes,nout)) {
0034 m_main_branch.set_tot_bytes(m_main_branch.tot_bytes()+add_bytes);
0035 m_main_branch.set_zip_bytes(m_main_branch.zip_bytes()+nout);
0036 status = true;
0037 }
0038 m_mutex.unlock();
0039 delete a_basket;
0040 return status;
0041 }
0042 }
0043 public:
0044 basket_add(imutex& a_mutex,ifile& a_main_file,
0045 branch& a_main_branch,branch& a_parallel_branch,
0046 std::vector<icol*>& a_cols,
0047 std::vector<branch*>& a_main_branches,
0048 bool a_row_mode)
0049 :parent(a_mutex,a_main_file,a_main_branch)
0050 ,m_parallel_branch(a_parallel_branch)
0051 ,m_cols(a_cols)
0052 ,m_main_branches(a_main_branches)
0053 ,m_row_mode(a_row_mode)
0054 {}
0055 protected:
0056 basket_add(const basket_add& a_from)
0057 :branch::iadd_basket(a_from)
0058 ,parent(a_from)
0059 ,m_parallel_branch(a_from.m_parallel_branch)
0060 ,m_cols(a_from.m_cols)
0061 ,m_main_branches(a_from.m_main_branches)
0062 ,m_row_mode(a_from.m_row_mode)
0063 {}
0064 basket_add& operator=(const basket_add&){return *this;}
0065 protected:
0066 branch& m_parallel_branch;
0067 std::vector<icol*>& m_cols;
0068 std::vector<branch*>& m_main_branches;
0069 bool m_row_mode;
0070 };
0071 public:
0072 virtual bool add_row(imutex& a_mutex,ifile& a_main_file) {
0073 if(m_cols.empty()) return false;
0074 {tools_vforit(icol*,m_cols,it) (*it)->add();}
0075 if(m_main_branches.size()!=m_cols.size()) {
0076 m_out << "tools::wroot::mt_ntuple_column_wise::add_row :"
0077 << " m_main_branches.size() (" << m_main_branches.size() << ") != "
0078 << "m_cols.size() (" << m_cols.size() << ")."
0079 << std::endl;
0080 return false;
0081 }
0082 {std::vector<branch*>::const_iterator itb = m_main_branches.begin();
0083 tools_vforit(icol*,m_cols,it) {
0084 branch* main_branch = (*itb);itb++;
0085 basket_add _badd(a_mutex,a_main_file,*main_branch,(*it)->get_branch(),m_cols,m_main_branches,m_row_mode);
0086 if(!(*it)->get_branch().pfill(_badd,m_nev)) return false;
0087 }}
0088 {tools_vforit(icol*,m_cols,it) (*it)->set_def();}
0089 return true;
0090 }
0091 virtual bool end_fill(imutex& a_mutex,ifile& a_main_file) {
0092 if(m_main_branches.size()!=m_cols.size()) {
0093 m_out << "tools::wroot::mt_ntuple_column_wise::end_fill :"
0094 << " m_main_branches.size() (" << m_main_branches.size() << ") != "
0095 << "m_cols.size() (" << m_cols.size() << ")."
0096 << std::endl;
0097 return false;
0098 }
0099 std::vector<branch*>::const_iterator itb = m_main_branches.begin();
0100 tools_vforit(icol*,m_cols,it) {
0101 branch* main_branch = (*itb);itb++;
0102 basket_add _badd(a_mutex,a_main_file,*main_branch,(*it)->get_branch(),m_cols,m_main_branches,m_row_mode);
0103 if(!(*it)->get_branch().end_pfill(_badd)) return false;
0104 }
0105 if(m_row_mode) {
0106 size_t number;
0107 bool status = flush_remaining_baskets(number,a_mutex,a_main_file,m_cols,m_main_branches);
0108 if(number) {
0109 m_out << "tools::wroot::mt_ntuple_column_wise::end_fill : it remained " << number << " baskets not written on file." << std::endl;
0110 status = false;
0111 }
0112 if(!status) return false;
0113 }
0114 return end_leaves(a_mutex);
0115 }
0116 public:
0117 mt_ntuple_column_wise(std::ostream& a_out,bool a_byte_swap,uint32 a_compression,seek a_seek_directory,
0118 std::vector<branch*>& a_main_branches,
0119 const std::string& a_name,const std::string& a_title,
0120 bool a_row_mode,uint32 a_nev,
0121 bool a_verbose)
0122 :parent(a_out,a_byte_swap,a_compression,a_seek_directory,a_name,a_title,a_verbose)
0123 ,m_main_branches(a_main_branches)
0124 ,m_row_mode(a_row_mode)
0125 ,m_nev(a_nev)
0126 {
0127 if(m_row_mode) {
0128 if(!m_nev) m_nev = 4000; //4000*sizeof(double) = 32000 = default basket size.
0129 } else {
0130 m_nev = 0;
0131 }
0132 }
0133
0134 mt_ntuple_column_wise(std::ostream& a_out,bool a_byte_swap,uint32 a_compression,seek a_seek_directory,
0135 std::vector<branch*>& a_main_branches,
0136 const std::vector<uint32>& a_basket_sizes,
0137 const ntuple_booking& a_bkg,
0138 bool a_row_mode,uint32 a_nev,
0139 bool a_verbose)
0140 :parent(a_out,a_byte_swap,a_compression,a_seek_directory,a_basket_sizes,a_bkg,a_verbose)
0141 ,m_main_branches(a_main_branches)
0142 ,m_row_mode(a_row_mode)
0143 ,m_nev(a_nev)
0144 {
0145 if(m_row_mode) {
0146 if(!m_nev) m_nev = 4000;
0147 } else {
0148 m_nev = 0;
0149 }
0150 }
0151
0152 #ifdef tools_wroot_mt_ntuple_column_wise //g4tools backcomp :
0153 mt_ntuple_column_wise(std::ostream& a_out,bool a_byte_swap,uint32 a_compression,seek a_seek_directory,
0154 std::vector<branch*>& a_main_branches,
0155 const std::vector<uint32>& a_basket_sizes,
0156 const ntuple_booking& a_bkg,
0157 bool a_verbose)
0158 :parent(a_out,a_byte_swap,a_compression,a_seek_directory,a_basket_sizes,a_bkg,a_verbose)
0159 ,m_main_branches(a_main_branches)
0160 ,m_row_mode(false)
0161 ,m_nev(0)
0162 {
0163 if(m_row_mode) {
0164 if(!m_nev) m_nev = 4000;
0165 } else {
0166 m_nev = 0;
0167 }
0168 }
0169 #endif
0170
0171 virtual ~mt_ntuple_column_wise() {}
0172 protected:
0173 mt_ntuple_column_wise(const mt_ntuple_column_wise& a_from)
0174 :imt_ntuple(a_from)
0175 ,parent(a_from)
0176 ,m_main_branches(a_from.m_main_branches)
0177 ,m_row_mode(a_from.m_row_mode)
0178 ,m_nev(a_from.m_nev)
0179 {}
0180 mt_ntuple_column_wise& operator=(const mt_ntuple_column_wise& a_from){parent::operator=(a_from);return *this;}
0181 protected:
0182 static bool ready_to_flush_baskets(std::vector<icol*>& a_cols) {
0183 //return true if all parallel branches have at least one basket in their m_parallel_baskets.
0184 if(a_cols.empty()) return false;
0185 tools_vforit(icol*,a_cols,it) {
0186 branch& _branch = (*it)->get_branch();
0187 if(_branch.m_parallel_baskets.empty()) return false;
0188 }
0189 return true;
0190 }
0191 static bool flush_baskets(imutex& a_mutex,ifile& a_main_file,std::vector<icol*>& a_cols,std::vector<branch*>& a_main_branches) {
0192 a_mutex.lock();
0193 bool status = true;
0194 std::vector<branch*>::const_iterator itb = a_main_branches.begin();
0195 tools_vforit(icol*,a_cols,it) {
0196 branch& _branch = (*it)->get_branch();
0197 basket* _front_basket = _branch.m_parallel_baskets.front();
0198 branch* main_branch = (*itb);itb++;
0199 if(status) {
0200 uint32 add_bytes,nout;
0201 if(main_branch->add_basket(a_main_file,*_front_basket,add_bytes,nout)) {
0202 main_branch->set_tot_bytes(main_branch->tot_bytes()+add_bytes);
0203 main_branch->set_zip_bytes(main_branch->zip_bytes()+nout);
0204 } else {
0205 status = false;
0206 }
0207 }
0208 _branch.m_parallel_baskets.erase(_branch.m_parallel_baskets.begin());
0209 delete _front_basket;
0210 }
0211 a_mutex.unlock();
0212 return status;
0213 }
0214
0215 static bool flush_remaining_baskets(size_t& a_number,imutex& a_mutex,ifile& a_main_file,std::vector<icol*>& a_cols,std::vector<branch*>& a_main_branches) {
0216 a_number = 0;
0217 while(ready_to_flush_baskets(a_cols)) {
0218 if(!flush_baskets(a_mutex,a_main_file,a_cols,a_main_branches)) return false;
0219 }
0220 // look for pending baskets.
0221 {tools_vforit(icol*,a_cols,it) {
0222 branch& _branch = (*it)->get_branch();
0223 a_number += _branch.m_parallel_baskets.size();
0224 }}
0225 {tools_vforit(icol*,a_cols,it) {
0226 branch& _branch = (*it)->get_branch();
0227 safe_clear(_branch.m_parallel_baskets);
0228 }}
0229 return true;
0230 }
0231
0232 bool end_leaves(imutex& a_mutex) const {
0233
0234 #include "MT_SET_MAX.icc"
0235
0236 std::vector<icol*>::const_iterator pit = m_cols.begin();
0237 tools_vforcit(branch*,m_main_branches,mit) {
0238 if((*mit)->leaves().empty()) {
0239 m_out << "tools::wroot::mt_ntuple_column_wise::end_leaves :"
0240 << " branch " << (*mit)->name() << " without leaf." << std::endl;
0241 return false;
0242 }
0243
0244 base_leaf* _mleaf = *((*mit)->leaves().begin());
0245 base_leaf* _pleaf = (*pit)->get_leaf(); pit++; //WARNING.
0246
0247 TOOLS_WROOT_MT_NTUPLE_STRING_SET_MAX
0248
0249 }
0250 #undef TOOLS_WROOT_MT_NTUPLE_STRING_SET_MAX
0251
0252 return true;
0253 }
0254 protected:
0255 std::vector<branch*>& m_main_branches;
0256 bool m_row_mode;
0257 uint32 m_nev;
0258 };
0259
0260 }}
0261
0262 #endif