#include #include #include #include #include "TH1D.h" #include "TH2D.h" #include "TProcPool.h" #include "TFile.h" //start of the class definition struct InputClass { public: std::string filename; Int_t seed; InputClass(std::string filename_, Int_t seed_) : filename(filename_), seed(seed_) { } }; struct OutputClass { public: std::vector outputs; OutputClass() { } }; //function used to gather all the outputs into a single one (by appending) OutputClass reducer(const std::vector &results) { OutputClass result; //NOTE the absence of s !! will be the return variable for(auto&& i : results) { std::cout << "{"; for(std::size_t j = 0; j < i.outputs.size(); j++) { std::cout << i.outputs[j]; if(j != i.outputs.size()-1) std::cout << ", "; } std::cout << "}" << std::endl; result.outputs.insert(result.outputs.end(), i.outputs.begin(), i.outputs.end()); //means insert at the end of outputs all the elements of i.outputs } return result; } // now the actual main method int main() { std::size_t nData(1000); // Create a datafile to play with { auto ofile(std::unique_ptr(TFile::Open("test.root", "recreate"))); TTree ttree("tree", ""); UInt_t intBranch; ttree.Branch("intBranch", &intBranch); for(std::size_t i = 0; i < nData; i++) { intBranch = i; ttree.Fill(); } ttree.Write(); } //effectively starts here std::size_t numCores(2); TProcPool pool(numCores); // processing pool, argument is # of processes, so actually it is not the number of cores on the machine but the number of core we want the program to use. std::vector seeds; for(std::size_t i = 0; i < numCores; i++) seeds.emplace_back("test.root", i+1); //we are initializing numCores instances of InputClass auto readFile = [](InputClass input) { auto ifile(std::unique_ptr(TFile::Open(input.filename.c_str()))); TTree *itree(nullptr); ifile->GetObject("tree", itree); UInt_t myIntBranch; itree->SetBranchAddress("intBranch", &myIntBranch); ULong64_t nEntries(itree->GetEntries()); OutputClass result; for(std::size_t i = 0; i < nEntries; i++) { itree->GetEntry(i); if(myIntBranch % input.seed == 0) result.outputs.push_back(myIntBranch); } return result; }; //The call to the multithreading function MapReduce auto result = pool.MapReduce(readFile, seeds, reducer); return 0; }