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