Logo ROOT   6.08/07
Reference Guide
TTreeProcessor.cxx
Go to the documentation of this file.
1 // @(#)root/thread:$Id$
2 // Author: Enric Tejedor, CERN 12/09/2016
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TTreeProcessor
13  \brief A class to process the entries of a TTree in parallel.
14 
15 By means of its Process method, TTProcessor provides a way to process the
16 entries of a TTree in parallel. When invoking TTProcessor::Process, the user
17 passes a function whose only parameter is a TTreeReader. The function iterates
18 on a subrange of entries by using that TTreeReader.
19 
20 The implementation of TTreeProcessor parallelizes the processing of the subranges,
21 each corresponding to a cluster in the TTree. This is possible thanks to the use
22 of a ROOT::TThreadedObject, so that each thread works with its own TFile and TTree
23 objects.
24 */
25 
26 #include "TROOT.h"
27 #include "ROOT/TTreeProcessor.hxx"
28 
29 #include "tbb/task.h"
30 #include "tbb/task_group.h"
31 
32 using namespace ROOT;
33 
34 //////////////////////////////////////////////////////////////////////////////
35 /// Process the entries of a TTree in parallel. The user-provided function
36 /// receives a TTreeReader which can be used to iterate on a subrange of
37 /// entries
38 /// ~~~{.cpp}
39 /// TTreeProcessor::Process([](TTreeReader& readerSubRange) {
40 /// // Select branches to read
41 /// while (readerSubRange.next()) {
42 /// // Use content of current entry
43 /// }
44 /// });
45 /// ~~~
46 /// The user needs to be aware that each of the subranges can potentially
47 /// be processed in parallel. This means that the code of the user function
48 /// should be thread safe.
49 ///
50 /// \param[in] func User-defined function that processes a subrange of entries
51 void TTreeProcessor::Process(std::function<void(TTreeReader&)> func)
52 {
53  // Enable this IMT use case (activate its locks)
55 
56  auto clusterIter = treeView->GetClusterIterator();
57  Long64_t start = 0, end = 0;
58 
59  // Create task group - assume number of threads has been initialized via ROOT::EnableImplicitMT
60  tbb::task_group g;
61 
62  // Iterate over the clusters and generate a task for each of them
63  while ((start = clusterIter()) < treeView->GetEntries()) {
64  end = clusterIter.GetNextEntry();
65 
66  g.run([this, &func, start, end]() {
67  auto tr = treeView->GetTreeReader();
68  tr->SetEntriesRange(start, end);
69  func(*tr);
70  });
71  }
72 
73  g.wait();
74 }
Long64_t GetNextEntry()
Definition: TTree.h:289
long long Long64_t
Definition: RtypesCore.h:69
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:48
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
void Process(std::function< void(TTreeReader &)> func)
Process the entries of a TTree in parallel.
TTree::TClusterIterator GetClusterIterator()
Get the cluster iterator for the tree of this view, starting from entry zero.
Long64_t GetEntries() const
Get the number of entries of the tree of this view.
double func(double *x, double *p)
Definition: stressTF1.cxx:213
ROOT::TThreadedObject< ROOT::Internal::TTreeView > treeView
! Threaded object with <file,tree> per thread
std::unique_ptr< TTreeReader > GetTreeReader() const
Get a TTreeReader for the tree of this view.